It's not a Bug, it's a Feature! UVA - 658 (最短路)
阿新 • • 發佈:2018-11-15
考慮到狀態數較多,我們不選擇存點,而是每次檢測可行的變化方式(即邊)來前進。考慮到所有的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; } }