題意很難讀。比賽時讀了半個小時,賽後又讀了一個小時,仍是有些模棱兩可。最後又問了問,大概知道是什麼意思了。c++
就是給定一些航班,每一個航班雙向鏈接一對城市。要求從西安出發,必須先到達上海而後到達青島,而後從青島回到上海浦東機場的最小費用spa
其中,每一個機場有登機區和降落區,每一個機場的登機區和降落區都只能通過一次。上海有浦東機場和虹橋機場兩個,兩個機場間能夠不坐飛機而且不消耗費用blog
對於點容量限制,能夠經過拆點來限制點容量,這是基本操做get
對於路徑限制,能夠經過源點匯點的設定來作到。若最大流爲滿則存在路徑string
#include<bits/stdc++.h> using namespace std; const int maxn=2e4+8; const int INF=0x7f7f7f7f; struct fuck{ int u,v,cap,w,next; }edge[maxn<<4]; int head[maxn<<1]; int tol; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w,int cap) { edge[tol].u=u; edge[tol].v=v; edge[tol].cap=cap; edge[tol].w=w; edge[tol].next=head[u]; head[u]=tol++; edge[tol].u=v; edge[tol].v=u; edge[tol].w=-w; edge[tol].cap=0; edge[tol].next=head[v]; head[v]=tol++; } map<string,int> mp; int idx; int getid(char s[]) { if(mp.count(s)!=0) return mp[s]; mp[s]=idx;addedge(idx*2-1,idx*2,0,1);idx++; return idx-1; } int dis[maxn<<1],pre[maxn<<1]; bool vis[maxn<<1]; bool spfa(int sour,int sink) { queue<int> q; q.push(sour); memset(dis,INF,sizeof(dis)); memset(vis,false,sizeof(vis)); dis[sour]=0;vis[sour]=true;pre[sour]=-1; int i,u,v; while(!q.empty()) { u=q.front();q.pop(); vis[u]=false; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(edge[i].cap>0&&edge[i].w+dis[u]<dis[v]) { dis[v]=dis[u]+edge[i].w; pre[v]=i; if(!vis[v]) vis[v]=true,q.push(v); } } } if(dis[sink]>=INF) return false; return true; } void Minicost(int sour,int sink) { int co,fl; co=fl=0; while(spfa(sour,sink)) { int mi=INF; for(int i=pre[sink];i!=-1;i=pre[edge[i^1].v]){ if(mi>edge[i].cap) mi=edge[i].cap; } for(int i=pre[sink];i!=-1;i=pre[edge[i^1].v]){ edge[i].cap-=mi; edge[i^1].cap+=mi; } fl+=mi; co+=dis[sink]*mi; } if(fl==3) printf("%d\n",co); else printf("-1\n"); } int main() { int t; scanf("%d",&t); while(t--) { int m; scanf("%d",&m); init();idx=1; mp.clear(); mp["Xian"]=idx;addedge(idx*2-1,idx*2,0,1);idx++; mp["Qingdao"]=idx;addedge(idx*2-1,idx*2,0,2);idx++; mp["Hongqiao"]=idx;addedge(idx*2-1,idx*2,0,2);idx++; mp["Pudong"]=idx;addedge(idx*2-1,idx*2,0,1);idx++; while(m--) { char s[12],c[12]; int w; scanf("%s%s%d",s,c,&w); int u=getid(s); int v=getid(c); addedge(u*2,v*2-1,w,INF); addedge(v*2,u*2-1,w,INF); } int sour=0,sink=idx*2-1; addedge(sour,3*2-1,0,2); addedge(sour,4*2-1,0,1); addedge(1*2,sink,0,1); addedge(2*2,sink,0,2); Minicost(sour,sink); } return 0; }