标签:
给出一个图,从一号节点去N号节点,再回来。
但是不能经过相同的边,即一条边最多只能够走一次。
求来回的总长度的最小值。
转化:
求1号到N号的2条没有公共边的路径,这样就相当于在这个图中所有边的容量都是1,现在要找2条增广路,得到的流量为2,就相当于求流量为2的最小费用流。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 6 using namespace std; 7 8 const int maxn=1005; 9 const int inf=0x3f3f3f3f; 10 const int s=1; 11 int t; 12 13 inline int min(int x,int y) 14 { 15 return x<y?x:y; 16 } 17 18 struct Edge 19 { 20 int to,cap,cost,rev; 21 }; 22 vector<Edge>edge[maxn]; 23 int prev[maxn]; 24 int pree[maxn]; 25 int dist[maxn]; 26 int vis[maxn]; 27 28 void addedge(int from,int to,int cap,int cost) 29 { 30 edge[from].push_back((Edge){to,cap,cost,edge[to].size()}); 31 edge[to].push_back((Edge){from,0,-cost,edge[from].size()-1}); 32 } 33 34 void build_graph(int n,int m) 35 { 36 t=n; 37 for(int i=1;i<=m;i++) 38 { 39 int u,v,w; 40 scanf("%d%d%d",&u,&v,&w); 41 addedge(u,v,1,w); 42 addedge(v,u,1,w); 43 } 44 } 45 46 void spfa(int n) 47 { 48 memset(vis,false,sizeof vis); 49 for(int i=2;i<=n;i++) 50 dist[i]=inf; 51 dist[1]=0; 52 queue<int>que; 53 while(!que.empty()) 54 que.pop(); 55 que.push(s); 56 vis[s]=true; 57 while(!que.empty()) 58 { 59 int u=que.front(); 60 que.pop(); 61 vis[u]=false; 62 for(int i=0;i<edge[u].size();i++) 63 { 64 Edge &e=edge[u][i]; 65 if(e.cap>0&&dist[e.to]>dist[u]+e.cost) 66 { 67 dist[e.to]=dist[u]+e.cost; 68 prev[e.to]=u; 69 pree[e.to]=i; 70 if(!vis[e.to]) 71 { 72 que.push(e.to); 73 vis[e.to]=true; 74 } 75 } 76 } 77 } 78 } 79 80 int min_cost_flow(int f,int n) 81 { 82 int ret=0; 83 while(f>0) 84 { 85 spfa(n); 86 int d=f; 87 for(int v=t;v!=s;v=prev[v]) 88 { 89 d=min(d,edge[prev[v]][pree[v]].cap); 90 } 91 f-=d; 92 ret+=dist[t]*d; 93 for(int v=t;v!=s;v=prev[v]) 94 { 95 Edge &e=edge[prev[v]][pree[v]]; 96 e.cap-=d; 97 edge[e.to][e.rev].cap+=d; 98 } 99 } 100 return ret; 101 } 102 103 int main() 104 { 105 int n,m; 106 while(~scanf("%d%d",&n,&m)) 107 { 108 build_graph(n,m); 109 110 printf("%d\n",min_cost_flow(2,n)); 111 } 112 return 0; 113 }
标签:
原文地址:http://www.cnblogs.com/-maybe/p/4694306.html