ZKW优化费用流
#include <bits/stdc++.h> using namespace std; typedef long long ll; double pi=acos(-1.0); double eps=1e-8; const int mod=1e9+7; bool vis[200001]; int dist[200001]; int n,m,s,t,ans=0; int nedge=-1,p[200001],c[200001],cc[200001],nex[200001],head[200001]; inline void addedge(int x,int y,int z,int zz) { p[++nedge]=y; c[nedge]=z; cc[nedge]=zz; nex[nedge]=head[x]; head[x]=nedge; } inline bool spfa(int s,int t) { memset(vis,0,sizeof vis); for(int i=0; i<=n; i++)dist[i]=1e9; dist[t]=0; vis[t]=1; deque<int>q; q.push_back(t); while(!q.empty()) { int now=q.front(); q.pop_front(); for(int k=head[now]; k>-1; k=nex[k])if(c[k^1]&&dist[p[k]]>dist[now]-cc[k]) { dist[p[k]]=dist[now]-cc[k]; if(!vis[p[k]]) { vis[p[k]]=1; if(!q.empty()&&dist[p[k]]<dist[q.front()])q.push_front(p[k]); else q.push_back(p[k]); } } vis[now]=0; } return dist[s]<1e9; } inline int dfs(int x,int low) { if(x==t) { vis[t]=1; return low; } int used=0,a; vis[x]=1; for(int k=head[x]; k>-1; k=nex[k])if(!vis[p[k]]&&c[k]&&dist[x]-cc[k]==dist[p[k]]) { a=dfs(p[k],min(c[k],low-used)); if(a)ans+=a*cc[k],c[k]-=a,c[k^1]+=a,used+=a; if(used==low)break; } return used; } inline int costflow() { int flow=0; while(spfa(s,t)) { vis[t]=1; while(vis[t]) { memset(vis,0,sizeof vis); flow+=dfs(s,1e9); } } return flow; } map<string,int>mp; int cnt=0; int main() { int T; scanf ("%d",&T); while (T--) { cnt=0; mp.clear(); memset(nex,-1,sizeof nex); memset(head,-1,sizeof head); nedge=-1; ans=0; scanf("%d",&m); char s1[20],s2[20]; int val; for(int i=1; i<=m; i++) { scanf ("%s%s%d",s1,s2,&val); int x,y; if (mp[s1]==0) { cnt+=2; x=mp[s1]=cnt; addedge(x,x-1,1,0); addedge(x-1,x,0,0); addedge(x-1,x,1,0); addedge(x,x-1,0,0); } else x=mp[s1]; if (mp[s2]==0) { cnt+=2; y=mp[s2]=cnt; addedge(y,y-1,1,0); addedge(y-1,y,0,0); addedge(y-1,y,1,0); addedge(y,y-1,0,0); } else y=mp[s2]; addedge(x,y-1,1,val); addedge(y-1,x,0,-val); addedge(y,x-1,1,val); addedge(x-1,y,0,-val); } if (mp["Dalian"]==0||mp["Xian"]==0||mp["Shanghai"]==0) { printf ("-1\n"); continue; } n=cnt+2; s=++cnt; t=++cnt; addedge(s,mp["Shanghai"],2,0); addedge(mp["Shanghai"],s,0,0); addedge(mp["Dalian"],t,1,0); addedge(t,mp["Dalian"],0,0); addedge(mp["Xian"],t,1,0); addedge(t,mp["Xian"],0,0); if (costflow()==2) printf("%d\n",ans); else printf ("-1\n"); } return 0; }