首页 > 代码库 > Uva 10806 来回最短路,不重复,MCMF
Uva 10806 来回最短路,不重复,MCMF
题目链接:https://uva.onlinejudge.org/external/108/10806.pdf
题意:无向图,从1到n来回的最短路,不走重复路。
分析:可以考虑为1到n的流量为2时的最小花费;
建图: 一个点到一个点的容量为1,费用为距离。
1 #include <cstring> 2 #include <cstdio> 3 #include <vector> 4 #include <queue> 5 #include <algorithm> 6 #include <iostream> 7 using namespace std; 8 9 const int maxn = 100 + 10, INF = 1000000000; 10 11 12 struct Edge 13 { 14 int from, to, cap, flow, cost; 15 }; 16 17 struct MCMF 18 { 19 int n, m; 20 vector<Edge> edges; 21 vector<int> G[maxn]; 22 bool inq[maxn]; // 是否在队列中 23 int d[maxn]; // Bellman-Ford 24 int p[maxn]; // 上一条弧 25 int a[maxn]; // 可改进量 26 27 void init(int n) 28 { 29 this->n = n; 30 for(int i = 0; i < n; i++) G[i].clear(); 31 edges.clear(); 32 } 33 34 void AddEdge(int from, int to, int cap, int cost) 35 { 36 edges.push_back((Edge) 37 { 38 from, to, cap, 0, cost 39 }); 40 edges.push_back((Edge) 41 { 42 to, from, 0, 0, -cost 43 }); 44 m = edges.size(); 45 G[from].push_back(m-2); 46 G[to].push_back(m-1); 47 } 48 49 bool BellmanFord(int s, int t, int &flow, long long& cost) 50 { 51 memset(inq,0,sizeof(inq)); 52 for(int i=0;i<n;i++) 53 d[i] = INF; 54 d[s] = 0; 55 inq[s] = true; 56 p[s] = 0; 57 a[s] = INF; 58 59 queue<int> Q; 60 Q.push(s); 61 while(!Q.empty()) 62 { 63 int u = Q.front(); 64 Q.pop(); 65 inq[u] = false; 66 for(int i = 0; i < G[u].size(); i++) 67 { 68 Edge& e = edges[G[u][i]]; 69 if(e.cap > e.flow && d[e.to] > d[u] + e.cost) 70 { 71 d[e.to] = d[u] + e.cost; 72 p[e.to] = G[u][i]; 73 a[e.to] = min(a[u], e.cap - e.flow); 74 if(!inq[e.to]) 75 { 76 Q.push(e.to); 77 inq[e.to] = true; 78 } 79 } 80 } 81 } 82 if(d[t] == INF) return false; //s-t 不连通,失败退出 83 flow += a[t]; 84 cost += (long long)d[t] * (long long)a[t]; 85 int u = t; 86 while(u != s) 87 { 88 edges[p[u]].flow += a[t]; 89 edges[p[u]^1].flow -= a[t]; 90 u = edges[p[u]].from; 91 } 92 return true; 93 } 94 95 pair<long long,int>Mincost(int s, int t) 96 { 97 long long cost = 0; 98 int flow = 0; 99 while(BellmanFord(s, t, flow, cost));100 return pair<long long ,int>{cost,flow};101 }102 };103 104 MCMF solver;105 int n;106 107 108 int main()109 {110 while(true)111 {112 scanf("%d", &n);113 if(n == 0) break;114 solver.init(n + 1);115 int m, from, to, cost;116 scanf("%d", &m);117 for(int i = 0; i < m; i++)118 {119 scanf("%d%d%d", &from, &to, &cost);120 solver.AddEdge(from, to, 1, cost);121 solver.AddEdge(to, from, 1, cost);122 }123 solver.AddEdge(0, 1, 2, 0);124 125 pair<long long,int> ans = solver.Mincost(0, n);126 int flow = ans.second;127 128 if(flow != 2)129 puts("Back to jail");130 else131 printf("%lld\n", ans.first);132 }133 return 0;134 }
Uva 10806 来回最短路,不重复,MCMF
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。