洛谷 P2770 航空路线问题【最大费用最大流】
2018-02-07 21:43
429 查看
记得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 ,cnt=1,dis ,fr ,a [2],ans,sum; bool v ; string c1,c2,ha ; 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:航空路线问题【最大费用最大流】
- 洛谷P2770 航空路线问题(费用流)
- 【网络流24题】航空路线问题(最大费用流)
- 网络流24题(11)航空路线问题(最大费用最大流)
- 【网络流24题】No.11(航空路线问题 最长不相交路径 最大费用流)
- [题解] [网络流二十四题(十一)] 航空路线问题(最大费用最大流)
- 洛谷 P4015 运输问题 【最小费用最大流+最大费用最大流】
- 洛谷 P4012 深海机器人问题 【最大费用最大流】
- 洛谷 P3356 火星探险问题 【最大费用最大流】
- 洛谷 P4013 数字梯形问题【最大费用最大流】
- LOJ6122 「网络流 24 题 - 18」 航空路线问题 最长不相交路径 坠大费用坠大流
- P2770 航空路线问题
- 洛谷 P4014 分配问题 【最小费用最大流+最大费用最大流】
- 洛谷 P3358 最长k可重区间集问题 【最大费用最大流】
- 2014湘潭全国邀请赛I题 Intervals /POJ 3680 / 在限制次数下取有权区间使权最大/小问题(费用流)
- 洛谷P3358:最长k可重区间集问题(最大费用最大流)
- 最大流和费用流问题中使用反向弧的原因
- 线性规划与网络流24题之海底机器人问题 最大费用最大流
- 【网络流24题】航空路线问题
- 线性规划与网络流24题之最长k可重区间集问题 最大权不相交路径(最大费用最大流)