1. 程式人生 > >It's not a Bug, it's a Feature! UVA - 658 (最短路)

It's not a Bug, it's a Feature! UVA - 658 (最短路)

考慮到狀態數較多,我們不選擇存點,而是每次檢測可行的變化方式(即邊)來前進。考慮到所有的bug都只有存在和不存在兩種情況所以選擇使用二進位制進行儲存。

AC程式碼:

#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
struct MOVE{
	string in,out;
	ll w;
	friend bool operator<(MOVE a,MOVE b){
		return a.w<b.w;
	}
}mov[105];
struct node{
	int id;ll w;
	node(int id=0,ll w=0):id(id),w(w){}
	friend bool operator<(node a,node b){
		return a.w>b.w;
	}
};
int n,m;
priority_queue<node> q;
ll dis[1<<21];int vis[1<<21];
bool check(int id,string in)
{
	for(int i=0;i<n;i++)
	{
		if(in[i]=='-'){
			if(((id>>i)&1)) return false;
		}else if(in[i]=='+'){
			if(!((id>>i)&1)) return false;
		}else{
			continue;
		}
	}
	return true;
}
int change(int id,string out)
{
	for(int i=0;i<n;i++){
		if(out[i]=='-'){
			id=(~((~id)|(1<<i)));
		}
		else if(out[i]=='+'){
			id|=(1<<i);
		}
	}
	return id;
}
void Dijkstra()
{
	int beg=0;
	for(int i=0;i<n;i++) beg|=(1<<i);
	for(int i=0;i<(1<<21);i++) dis[i]=inf;
	memset(vis,0,sizeof(vis));
	while(!q.empty()) q.pop();
	q.push(node(beg,0)),dis[beg]=0;
	while(!q.empty())
	{
		node s=q.top();
		q.pop();
		int id=s.id;
		if(vis[id]) continue;
		vis[id]=1;
		if(dis[id]!=s.w) continue;
		for(int i=1;i<=m;i++)
		{
			if(check(s.id,mov[i].in))
			{
				int nxtid=change(s.id,mov[i].out);
				if(dis[nxtid]>dis[s.id]+mov[i].w)
				{
					dis[nxtid]=dis[s.id]+mov[i].w;
					q.push(node(nxtid,dis[nxtid]));
                }
			}
		}
	}
}
int main()
{
	int tot=0;
	while(~scanf("%d%d",&n,&m)&&(n&&m))
	{
		for(int i=1;i<=m;i++)
		{
			cin>>mov[i].w>>mov[i].in>>mov[i].out;
		}
		Dijkstra();
		int obj=0;
		//if(tot) printf("\n");
		printf("Product %d\n",++tot);
		if(dis[obj]==inf) printf("Bugs cannot be fixed.\n");
		else printf("Fastest sequence takes %lld seconds.\n",dis[obj]);
		cout<<endl;
	}
}