It's not a Bug, it's a Feature!-----------優先佇列和spfa----做了很長時間!!!(好題!)
阿新 • • 發佈:2019-01-30
可以直接用位運算去操作:
①判定某些位置是否為1,如判定2、4位置為1,則轉化為判斷x|0101是否等於x。
②判定某些位置是否為0,如判定2、4位置為0,則轉化為判斷x&1010是否等於x。
③將某些位置轉化為1,如2、4位置轉化為1,則令x=x|0101。
④將某些位置轉化為0,如2、4位置轉化為0,則令x=x&1010。
在用二進位制表示狀態的基礎上採用這些位運算技巧之後,速度就變得比較快了。
用了兩種方法(優先佇列和spfa)
#include<cstdlib> #include<iostream> #include<sstream> #include<cstdio> #include<cmath> #include<cstring> #include <algorithm> #include<vector> #include<set> #include<queue> #define LL long long #define inf 1000000000 #define E 1e-9 #define N 100 #define M 2000000 using namespace std; int n,m,ans; char str1[25],str2[25]; int map[110][2][2],w[110]; int v[2000000]; typedef pair<int,int> pii; priority_queue<pii,vector<pii>,greater<pii> > q; int d[2000000],qu[2000000],inq[2000000]; void print(int p) { // for(int i=0; i<n; i++) // if(p&(1<<i)) // cout<<"1"; // else // cout<<"0"; } void spfa() { int r=0,f=0; int MAX=(1<<n); for(int i=0; i<MAX; i++) { d[i]=inf; inq[i]=0; } d[MAX-1]=0; qu[r++]=MAX-1; inq[MAX-1]=1; while(f<r) { int u=qu[f++]; if(f==M-1) f=0; inq[u]=0; for(int i=0; i<m; i++) { int t=u; if((t|map[i][0][0])==t&&(t&map[i][0][1])==t) { t|=map[i][1][0]; t&=(map[i][1][1]); if(d[t]>d[u]+w[i]) { d[t]=d[u]+w[i]; if(!inq[t]) { inq[t]=1; qu[r++]=t; if(r==M-1) r=0; } } } } } } int dfs() { while(!q.empty()) q.pop(); q.push(make_pair(0,(1<<n)-1)); while(!q.empty()) { pii u=q.top(); q.pop(); int p=u.second; v[p]=1;//只有出佇列時,才說明不用在考慮他了!!!! if(!p) return u.first; for(int i=0; i<m; i++) { int t=p; if((t|map[i][0][0])==t&&(t&map[i][0][1])==t) { t|=map[i][1][0]; t&=(map[i][1][1]); if(v[t]) continue; q.push(make_pair(u.first+w[i],t)); } } } return -1; } int main() { #ifndef ONLINE_JUDGE freopen("ex.in","r",stdin); #endif int ncase=0; while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m) break; memset(v,0,sizeof(v)); memset(map,0,sizeof(map)); for (int i=0; i<m; i++) { scanf("%d%s%s",&w[i],str1,str2); for(int j=0; j<n; j++) { if(str1[j]=='+') { map[i][0][0]+=(1<<j);/////////////////// } if(str2[j]=='+') { map[i][1][0]+=(1<<j); } if(str1[j]!='-') { map[i][0][1]+=(1<<j); } if(str2[j]!='-') { map[i][1][1]+=(1<<j); } } } int flag=dfs(); // spfa(); printf("Product %d\n",++ncase); // if(d[0]==inf) if(flag==-1) printf("Bugs cannot be fixed.\n"); else printf("Fastest sequence takes %d seconds.\n",flag); // printf("Fastest sequence takes %d seconds.\n",d[0]); printf("\n"); } return 0; }