跑最大费用最大流,把每个点拆开边权为1花费为1,连边时边权为1花费为0
开头和结尾单独处理边权为2.
字符串用map记录然后两遍dfs出结果即可。
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 string ss,mpp[105]; 4 map<string,int>mmp; 5 int n,m,head[205],d[205],f[205],cnt=-1,s,t,cost,ans[2][205]; 6 bool v[205]; 7 struct node{ 8 int nex,w,to,c,f; 9 }e[10005]; 10 void add(int x,int y,int w,int c) 11 { 12 e[++cnt].to=y;e[cnt].f=x;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;e[cnt].c=c; 13 e[++cnt].to=x;e[cnt].f=y;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;e[cnt].c=-c; 14 } 15 queue<int>q; 16 bool spfa() 17 { 18 memset(v,0,sizeof(v)); 19 memset(d,0,sizeof(d)); 20 v[s]=1;q.push(s); 21 memset(f,-1,sizeof(f)); 22 while(!q.empty()) 23 { 24 int x=q.front(); 25 q.pop();v[x]=0; 26 for(int i=head[x];i!=-1;i=e[i].nex) 27 { 28 int y=e[i].to; 29 if(d[y]<d[x]+e[i].c&&e[i].w) 30 { 31 d[y]=d[x]+e[i].c; 32 f[y]=i; 33 if(!v[y])v[y]=1,q.push(y); 34 } 35 } 36 } 37 if(d[t]==0)return 0;int inf=1e9; 38 for(int i=f[t];i!=-1;i=f[e[i].f])inf=min(inf,e[i].w); 39 for(int i=f[t];i!=-1;i=f[e[i].f])cost+=inf*e[i].c,e[i].w-=inf,e[i^1].w+=inf; 40 return 1; 41 } 42 void solve() 43 { 44 while(spfa());return; 45 } 46 void dfs(int x,int k) 47 { 48 if(x==n) 49 { 50 ans[k][++ans[k][0]]=x;return; 51 } 52 if(x%n!=ans[k][ans[k][0]]) 53 ans[k][++ans[k][0]]=x%n; 54 for(int i=head[x];i!=-1;i=e[i].nex) 55 { 56 57 if(e[i^1].w) 58 { 59 e[i^1].w=0; 60 dfs(e[i].to,k); 61 return; 62 } 63 } 64 } 65 int main() 66 { 67 scanf("%d%d",&n,&m); 68 memset(head,-1,sizeof(head)); 69 for(int i=1;i<=n;++i) 70 { 71 cin>>ss; 72 mmp[ss]=i; 73 mpp[i]=ss; 74 } 75 for(int i=1;i<=m;++i) 76 { 77 cin>>ss; 78 int x=mmp[ss]; 79 cin>>ss; 80 int y=mmp[ss]; 81 if(x==1&&y==n) 82 add(x+n,y,2,0); 83 add(x+n,y,1,0); 84 } 85 for(int i=2;i<n;++i) 86 { 87 add(i,i+n,1,1); 88 } 89 add(1,1+n,2,1); 90 add(n,n+n,2,1); 91 s=1;t=n*2; 92 solve(); 93 if(!cost){ 94 puts("No Solution!");return 0; 95 } 96 printf("%d\n",cost-2); 97 dfs(n+1,1); 98 dfs(n+1,0); 99 for(int i=1;i<=ans[1][0];++i)cout<<mpp[ans[1][i]]<<endl; 100 for(int i=ans[0][0]-1;i;--i)cout<<mpp[ans[0][i]]<<endl; 101 return 0; 102 }