日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[网络流24题] 航空路线问题 (费用流)

發(fā)布時(shí)間:2023/12/13 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [网络流24题] 航空路线问题 (费用流) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

洛谷傳送門(mén)?LOJ傳送門(mén)

這道題的圖還挺好想的吧

反正都是無(wú)向邊,起點(diǎn)走到終點(diǎn)再回到起點(diǎn),就相當(dāng)于從起點(diǎn)走$2$次到達(dá)終點(diǎn),且這兩次不經(jīng)過(guò)相同的點(diǎn),還要經(jīng)過(guò)盡可能多的點(diǎn)

很經(jīng)典的費(fèi)用流建圖

限制點(diǎn)通過(guò)次數(shù)->拆點(diǎn)連邊,流量為$1$,費(fèi)用為$1$

圖中的其他邊,編號(hào)較小的指向編號(hào)較大的,流量為$inf$,費(fèi)用為$0$

跑最大費(fèi)用最大流即可

注意有$1$直接到$n$的情況,所以其他邊流量要設(shè)置到至少大于$2$

至于輸出方案呢,在殘量網(wǎng)絡(luò)中,每次都$dfs$找出一條從匯點(diǎn)到源點(diǎn)的路徑即可

1 #include <map> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 #define N1 210 8 #define M1 40010 9 #define ll long long 10 #define dd double 11 #define inf 0x3f3f3f3f 12 using namespace std; 13 14 int gint() 15 { 16 int ret=0,fh=1;char c=getchar(); 17 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 18 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 19 return ret*fh; 20 } 21 struct Edge{ 22 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cost[M1<<1],cte; 23 void ae(int u,int v,int F,int C) 24 { 25 cte++; to[cte]=v; flow[cte]=F; cost[cte]=C; 26 nxt[cte]=head[u]; head[u]=cte; 27 } 28 }e,E; 29 int n,m,nn,S,T; 30 map<string,int>mp; 31 int que[M1],hd,tl,cost[N1],flow[N1],id[N1],use[N1]; 32 int spfa() 33 { 34 int x,j,v; 35 memset(flow,0,sizeof(flow)); 36 for(j=S;j<=T;j++) cost[j]=-inf; 37 hd=1,tl=0; que[++tl]=S; cost[S]=0; flow[S]=inf; use[S]=1; 38 while(hd<=tl) 39 { 40 x=que[hd++]; 41 for(j=e.head[x];j;j=e.nxt[j]) 42 { 43 v=e.to[j]; 44 if( cost[v]<cost[x]+e.cost[j] && e.flow[j]>0 ) 45 { 46 cost[v]=cost[x]+e.cost[j]; id[v]=j; 47 flow[v]=min(flow[x],e.flow[j]); 48 if(!use[v]) que[++tl]=v, use[v]=1; 49 } 50 } 51 use[x]=0; 52 } 53 return cost[T]!=-inf; 54 } 55 int stk[N1],tp; 56 void dfs(int x) 57 { 58 int j,v; 59 if(x<=n) stk[++tp]=x; 60 if(x==1) return; 61 for(j=e.head[x];j;j=e.nxt[j]) 62 { 63 v=e.to[j]; 64 if(!e.flow[j]) continue; 65 if(x>n){ 66 if(v==x-n) 67 { e.flow[j]--; dfs(v); break; } 68 }else{ 69 if(v<x+n) 70 { e.flow[j]--; dfs(v); break; } 71 } 72 } 73 } 74 char str[N1][20]; 75 void EK() 76 { 77 int x,tcost=0,mxflow=0,i,len,j; 78 while(spfa()) 79 { 80 mxflow+=flow[T]; tcost+=flow[T]*cost[T]; 81 for(x=T;x!=S;x=e.to[id[x]^1]) 82 { 83 e.flow[id[x]]-=flow[T]; 84 e.flow[id[x]^1]+=flow[T]; 85 } 86 } 87 if(mxflow<2){ puts("No Solution!"); return; } 88 printf("%d\n",tcost-2); 89 dfs(nn); 90 while(tp) 91 { 92 x=stk[tp]; len=strlen(str[x]); 93 for(j=0;j<len;j++) printf("%c",str[x][j]); 94 puts(""); tp--; 95 } 96 dfs(nn); 97 for(i=2;i<=tp;i++) 98 { 99 x=stk[i]; len=strlen(str[x]); 100 for(j=0;j<len;j++) printf("%c",str[x][j]); 101 puts(""); 102 } 103 } 104 int main() 105 { 106 scanf("%d%d",&n,&m); 107 string s;int i,j,x,y,len; 108 nn=n+n; S=0; T=nn+1; e.cte=1; 109 for(i=1;i<=n;i++) 110 { 111 cin>>s; mp[s]=i; len=s.length(); 112 for(j=0;j<len;j++) 113 str[i][j]=s[j]; 114 } 115 e.ae(1,1+n,2,1); e.ae(1+n,1,0,-1); 116 e.ae(n,n+n,2,1); e.ae(n+n,n,0,-1); 117 for(i=2;i<n;i++) e.ae(i,i+n,1,1), e.ae(i+n,i,0,-1); 118 for(i=1;i<=m;i++) 119 { 120 cin>>s; x=mp[s]; cin>>s; y=mp[s]; 121 if(x>y) swap(x,y); 122 e.ae(x+n,y,2,0); e.ae(y,x+n,0,0); 123 } 124 e.ae(S,1,2,0); e.ae(1,S,0,0); 125 e.ae(nn,T,2,0); e.ae(T,nn,0,0); 126 EK(); 127 return 0; 128 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/guapisolo/p/10295888.html

總結(jié)

以上是生活随笔為你收集整理的[网络流24题] 航空路线问题 (费用流)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。