(網路流24題大多需要spj,所以需要一個有spj的oj,本系列代碼均在www.oj.swust.edu.cn測試通過)
不知道為什麼會有這種奇怪的東西混進我的網路流,但既然出現了就寫一下吧,大體思路就是用二進位表示狀態,然後每個狀態可以轉移到另一個狀態,求一個最短路即可。
TMD我F1和F2看反了,讀題殺真是沒救了。
#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<iostream>#include<iomanip>#include<ctime>#include<cmath>#include<algorithm>#include<queue>using namespace std;int b1[10000];int b2[10000];int f1[10000];int f2[10000];char s[10000];int dis[2<<21];bool vis[2<<21];int v[5000];queue<int> que;int n,m;void spfa(){ memset(dis,0x3f,sizeof dis); dis[(1<<n)-1] = 0; que.push((1<<n)-1); int now; while(!que.empty()) { now = que.front(); vis[now] = false; que.pop(); for(int i=1,x,y;i<=m;++i) if(!(now&b2[i]) && (now|b1[i])==now) { x = now; x &= (~f1[i]); x |= f2[i]; if(dis[x]>dis[now]+v[i]) { dis[x] = dis[now]+v[i]; if(!vis[x]){ vis[x] = true; que.push(x); } } } }}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d",&v[i]); scanf("%s",s+1); int len=strlen(s+1); for(int j=1;j<=len;j++) { if(s[j]=='+') b1[i]=(b1[i]|(1<<(j-1))); else if(s[j]=='-') b2[i]=(b2[i]|(1<<(j-1))); } scanf("%s",s+1); len=strlen(s+1); for(int j=1;j<=len;j++) { if(s[j]=='+') f1[i]=(f1[i]|(1<<(j-1))); else if(s[j]=='-') f2[i]=(f2[i]|(1<<(j-1))); } swap(f1[i],f2[i]); } spfa(); if(dis[0]==0x3f3f3f3f) cout<<0; else cout<<dis[0]; return 0;}