1. 程式人生 > >洛谷 P2770 航空路線問題【最大費用最大流】

洛谷 P2770 航空路線問題【最大費用最大流】

無向圖 mark 記得 ostream wap while 除了 swa iostream

記得cnt=1!!因為是無向圖所以可以把回來的路看成另一條向東的路。字符串用map處理即可。拆點限制流量,除了1和n是(i,i+n,2)表示可以經過兩次,其他點都拆成(i,i+n,1),費用設為1,原圖中的邊(i,j)連接(i+n,j,1),註意特判掉i==q&&j==nst直接相連的情況,流量要設為2,然後跑最大費用最大流,如果流量小於2就是無解,否則分別從s和tdfs輸出方案。
記得輸出方案前先輸出一次起點。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map> #include<string> using namespace std; const int N=1000005,inf=1e9; int n,m,s,t,h[N],cnt=1,dis[N],fr[N],a[N][2],ans,sum; bool v[N]; string c1,c2,ha[N]; map<string,int>mp; struct qwe { int ne,no,to,va,c; }e[N<<2]; void add(int u,int v,int w,int c) { cnt++; e[cnt].ne=h[u]; e[cnt].no=u; e[cnt].to=v; e[cnt].va=w; e[cnt].c=c; h[u]=cnt; } void
ins(int u,int v,int w,int c) {//cout<<u<<" "<<v<<" "<<w<<endl; add(u,v,w,c); add(v,u,0,-c); } bool spfa() { for(int i=s;i<=t;i++) dis[i]=-inf; queue<int>q; q.push(s); dis[s]=0; v[s]=1; while(!q.empty()) { int
u=q.front(); q.pop(); v[u]=0; for(int i=h[u];i;i=e[i].ne) if(e[i].va&&dis[e[i].to]<dis[u]+e[i].c) { fr[e[i].to]=i; dis[e[i].to]=dis[u]+e[i].c; if(!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } }//cout<<dis[t]<<endl; return dis[t]!=-inf; } void mcf() { int x=inf; for(int i=fr[t];i;i=fr[e[i].no]) x=min(x,e[i].va); sum+=x; for(int i=fr[t];i;i=fr[e[i].no]) { e[i].va-=x; e[i^1].va+=x; ans+=x*e[i].c;//cout<<e[i].c<<endl; } } int main() { ios::sync_with_stdio(false); cin>>n>>m; s=1,t=n+n; for(int i=1;i<=n;i++) { cin>>c1; mp[c1]=i; ha[i]=c1; } for(int i=1;i<=m;i++) { cin>>c1>>c2;//cout<<c1<<endl<<c2<<endl; int x=mp[c1],y=mp[c2];//cout<<x<<" "<<y<<endl; if(x>y) swap(x,y); if(x==1&&y==n) ins(x+n,y,2,0); else ins(x+n,y,1,0); } ins(1,1+n,2,1); ins(n,n+n,2,1); for(int i=2;i<n;i++) ins(i,i+n,1,1); while(spfa()) mcf();//cout<<sum<<" "<<ans<<endl; if(sum<2) { puts("No Solution!"); return 0; } cout<<ans-2<<endl; cout<<ha[1]<<endl; for(int i=h[s+n],j,k;i;i=e[i].ne) if(!e[i].va&&!(i&1)) { k=e[i].to; while(k) { cout<<ha[k]<<endl; v[k]=1; for(j=h[k+n],k=0;j;j=e[j].ne) if(!e[j].va&&!(j&1)) { k=e[j].to; break; } } break; } for(int i=h[t-n],j,k;i;i=e[i].ne) if(!e[i^1].va&&(i&1)&&!v[e[i].to-n]) { k=e[i].to-n; while(k) { cout<<ha[k]<<endl; v[k]=1; for(j=h[k],k=0;j;j=e[j].ne) if(!e[j^1].va&&(j&1)) { k=e[j].to-n; break; } } break; } return 0; }

洛谷 P2770 航空路線問題【最大費用最大流】