网络流24题 洛谷 2770 航空路线问题
Posted horsepower2001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题 洛谷 2770 航空路线问题相关的知识,希望对你有一定的参考价值。
注意好处理读入和读出一定用cin!
#include <iostream> #include <cstring> #include <cstdio> #include <map> #define MX 80001 #define oo 12312312 #define S 1 #define T (n<<1) using namespace std; typedef struct edge_t { int u,v,c,w; }edge; edge e[MX]; int fst[MX],nxt[MX],lnum; int n,m; map<string,int>mp; string name[1001]; void addeg(int nu,int nv,int nc,int nw) { nxt[++lnum]=fst[nu]; fst[nu]=lnum; e[lnum]=(edge){nu,nv,nc,nw}; } void input() { string str1,str2; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { cin>>str1; mp[str1]=i; name[i]=str1; addeg(i,n+i,1,1); addeg(n+i,i,0,-1); } for(int i=1;i<=m;i++) { cin>>str1>>str2; addeg(mp[str1]+n,mp[str2],1,1),addeg(mp[str2],mp[str1]+n,0,-1); } addeg(1,n+1,1,1),addeg(n+1,1,0,-1); addeg(n,n*2,1,1),addeg(n*2,n,0,-1); } void init() { memset(fst,0xff,sizeof(fst)); lnum=-1; } int q[MX],pre[MX],dis[MX],inq[MX]; int spfa(int *flow,int *cost) { int h=0,t=1,x,y; memset(dis,0x9f,sizeof(dis)); memset(inq,0,sizeof(inq)); memset(pre,0,sizeof(pre)); q[++h]=S; dis[S]=0; pre[S]--; inq[S]=1; while(h>=t) { x=q[(t++)%MX]; inq[x]=0; for(int i=fst[x];i!=-1;i=nxt[i]) { y=e[i].v; if(e[i].c&&dis[y]<dis[x]+e[i].w) { dis[y]=dis[x]+e[i].w; pre[y]=i; if(!inq[y]) { q[(++h)%MX]=y; inq[y]=1; } } } } if(dis[T]<0)return 0; int now=pre[T],mxf=+oo,cst=0; while(now!=-1) { mxf=min(mxf,e[now].c); cst+=e[now].w; now=pre[e[now].u]; } now=pre[T]; while(now!=-1) { e[now].c-=mxf; e[now^1].c+=mxf; now=pre[e[now].u]; } *flow+=mxf; *cost+=cst*mxf; return 1; } int ans[1001];int anum=0; void out(int x) { ans[++anum]=x; for(int i=fst[x];i!=-1;i=nxt[i]) if(e[i].c==0&&e[i].w>=0) { out(e[i].v); e[i].c=1; return; } } int main() { int cost=0,flow=0; init(); input(); while(spfa(&flow,&cost));//求最大流 if(flow==0){printf("No Solution!\n");return 0;}//如果无解 else if(flow==1){cout<<2<<endl<<name[1]<<endl<<name[n]<<endl<<name[1]<<endl;return 0;}//如果只有一条合法航线(即只能在1,n之间往返) else//否则两条合法航线 { printf("%d\n",cost/2-1); out(S);//寻找经过的点 for(int i=1;i<=anum;i++)if(ans[i]<=n)cout<<name[ans[i]]<<endl; anum=0; out(S); for(int i=anum-2;i>=1;i--)if(ans[i]<=n)cout<<name[ans[i]]<<endl; } return 0; }
以上是关于网络流24题 洛谷 2770 航空路线问题的主要内容,如果未能解决你的问题,请参考以下文章