Our Journey of Xian Ends

Our Journey of Xian Ends

链接:here

参考http://blog.csdn.net/wangshuhe963/article/details/78516821

如果不理解为什么这么建模可以先做下面那道题

费用流~

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define LL long long
  4 const int maxv = 40010;
  5 const int maxe = 40010;
  6 const int inf = 0x3f3f3f3f;
  7 struct Edge{
  8     int head[maxv], nxt[maxe<<1], from[maxe<<1], to[maxe<<1], cap[maxe<<1], flow[maxe<<1], cost[maxe<<1];
  9     int cnt;
 10     void init(){
 11         cnt = 0;
 12         memset(head, -1, sizeof(head));
 13     }
 14     void add(int u, int v, int cp, int cst){
 15         from[cnt] = u;
 16         to[cnt] = v;
 17         nxt[cnt] = head[u];
 18         cap[cnt] = cp; flow[cnt] = 0; cost[cnt] = cst;
 19         head[u] = cnt++;
 20     }
 21 };
 22 struct MCMF{
 23     int n, m, s, t;
 24     Edge e;
 25     int inq[maxv], d[maxv], p[maxv], a[maxv];
 26 
 27     void init(int _n){
 28         n = _n;
 29         e.init();
 30     }
 31     void adde(int u, int v, int cap, int cost){
 32         e.add(u, v, cap, cost);
 33         e.add(v, u, 0, -cost);
 34     }
 35     bool bellmanFord(int s, int t, int &flow, int &cost){
 36         for(int i = 0; i < n; i++) d[i] = inf;
 37         memset(inq, 0, sizeof(inq));
 38         d[s] = 0; inq[s] = 1; p[s] = -1; a[s] = inf;
 39         queue<int> q;
 40         q.push(s);
 41         while(!q.empty()){
 42             int u = q.front(); q.pop();
 43             inq[u] = 0;
 44             for(int i = e.head[u]; ~i; i = e.nxt[i]){
 45                 int v = e.to[i];
 46                 if(e.cap[i] > e.flow[i] && d[v] > d[u] + e.cost[i]){
 47                     d[v] = d[u] + e.cost[i];
 48                     p[v] = i;
 49                     a[v] = min(a[u], e.cap[i] - e.flow[i]);
 50                     if(!inq[v]) q.push(v), inq[v] = 1;
 51                 }
 52             }
 53         }
 54         if(d[t] == inf) return 0;
 55         flow += a[t]; 
 56         cost += a[t] * d[t];
 57         int u = t;
 58         while(u != s){
 59             e.flow[p[u]] += a[t];
 60             e.flow[p[u] ^ 1] -= a[t];
 61             u = e.from[p[u]];
 62         }
 63         return 1;
 64     }
 65     int mincost(int s, int t){
 66         int flow = 0, cost = 0;
 67         while(bellmanFord(s, t, flow, cost));
 68         if(flow == 3) return cost;
 69         else return -1;
 70     }
 71 }solve;
 72 int cnt;
 73 map<string, int> mp;
 74 int ID(char *s){
 75     if(!mp.count(s)) mp[s] = cnt++;
 76     return mp[s];
 77 }
 78 int main(){
 79     int t;
 80     scanf("%d", &t);
 81     while(t--){
 82         mp.clear();
 83         cnt = 0;
 84         int n, m;
 85         scanf("%d", &m);
 86         n = m * 2;
 87         solve.init(n * 2 + 2);
 88         for(int i = 0; i < m; i++){
 89             char u[12], v[12];
 90             int w;
 91             scanf("%s %s %d", u, v, &w);
 92             int uu = ID(u), vv = ID(v);
 93             solve.adde(uu + n, vv, inf, w);
 94             solve.adde(vv + n, uu, inf, w);
 95         }
 96         int S = n * 2, T = n * 2 + 1;
 97         map<string, int> ::iterator it;
 98         for(it = mp.begin(); it != mp.end(); it++){
 99             int u = it->second;
100             if(it->first == "Xian"){
101                 solve.adde(u, u + n, 1, 0);
102                 solve.adde(u + n, T, 1, 0);
103             }else if(it->first == "Qingdao"){
104                 solve.adde(u, u + n, 2, 0);
105                 solve.adde(u + n, T, 2, 0);
106             }else if(it->first == "Hongqiao"){
107                 solve.adde(u, u + n, 2, 0);
108                 solve.adde(S, u, 2, 0);
109             }else if(it->first == "Pudong"){
110                 solve.adde(u, u + n, 1, 0);
111                 solve.adde(S, u, 1, 0);
112             }else{
113                 solve.adde(u, u + n, 1, 0);
114             }
115         }
116         solve.s = S; solve.t = T;
117         int ans = solve.mincost(S, T);
118         cout<<ans<<endl;
119     }
120 }
View Code

Our Journey of Dalian Ends

链接:here

基本是上面那个题的简化版,如果现场赛之前做过这道题,那上面那道应该没什么问题。

就是计算maxe的时候算错,总是忘记算拆点加入的边。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxv = 40010;
  4 const int maxe = 40010;
  5 const int inf = 0x3f3f3f3f;
  6 int head[maxv], cnt;
  7 struct Edge{
  8     int u, v, flow, cap, cost;
  9     int nxt;
 10     Edge(int u, int v, int flow, int cap, int cost, int nxt):u(u), v(v), flow(flow), cap(cap), cost(cost), nxt(nxt){}
 11     Edge(){}
 12 }e[maxe<<1];
 13 void add(int u, int v, int cap, int cost){
 14     e[cnt] = Edge(u, v, 0, cap, cost, head[u]);
 15     head[u] = cnt++;
 16     e[cnt] = Edge(v, u, 0, 0, -cost, head[v]);
 17     head[v] = cnt++;
 18 }
 19 void init(){
 20     cnt = 0;
 21     memset(head, -1, sizeof head);
 22 }
 23 int inq[maxv], d[maxv], p[maxv], a[maxv];
 24 int n, m;
 25 
 26 bool bellmanFord(int s, int t, int &flow, int &cost){
 27     for(int i = 0; i < n * 2 + 2; i++) d[i] = inf;
 28     memset(inq, 0, sizeof inq);
 29     inq[s] = 1; d[s] = 0; p[s] = -1; a[s] = inf;
 30     queue<int> q;
 31     q.push(s);
 32     while(!q.empty()){
 33         int u = q.front(); q.pop();
 34         inq[u] = 0;
 35         for(int i = head[u]; ~i; i = e[i].nxt){
 36             int v = e[i].v;
 37             if(e[i].cap > e[i].flow && d[v] > d[u] + e[i].cost){
 38                 d[v] = d[u] + e[i].cost;
 39                 p[v] = i;
 40                 a[v] = min(a[u], e[i].cap - e[i].flow);
 41                 if(!inq[v]) {
 42                     q.push(v);
 43                     inq[v] = 1;
 44                 }
 45             }
 46         }
 47     }
 48     if(d[t] == inf) return 0;
 49     int u = t;
 50     flow += a[t];
 51     cost += a[t] * d[t];
 52     while(u != s){
 53         e[p[u]].flow += a[t];
 54         e[p[u] ^ 1].flow -= a[t];
 55         u = e[p[u]].u;
 56     }
 57     return 1;
 58 }
 59 int mincost(int s, int t){
 60     int flow = 0, cost = 0;
 61     while(bellmanFord(s, t, flow, cost));
 62     if(flow == 2) return cost;
 63     else return -1;
 64 }
 65 int id;
 66 map<string, int> mp;
 67 int ID(char *s){
 68     if(!mp.count(s)) mp[s] = id++;
 69     return mp[s]; 
 70 }
 71 
 72 int main(){
 73     int t;
 74     scanf("%d", &t);
 75     while(t--){
 76         init();
 77         id = 0;
 78         mp.clear();
 79         scanf("%d", &m);
 80         n = m * 2;
 81         char s1[25], s2[25];
 82         int w;
 83         for(int i = 0; i < m; i++){
 84             scanf("%s %s %d", s1, s2, &w);
 85             int u = ID(s1), v = ID(s2);
 86             add(u + n, v, inf, w);
 87             add(v + n, u, inf, w);
 88         } 
 89         int S = n * 2, T = n * 2 + 1;
 90         map<string, int> :: iterator it;
 91         for(it = mp.begin(); it != mp.end(); it++){
 92             int u = it->second;
 93             if(it->first == "Shanghai"){
 94                 add(S, u, 2, 0);
 95                 add(u, u + n, 2, 0);
 96             }else if(it->first == "Xian" || it->first == "Dalian"){
 97                 add(u + n, T, 1, 0);
 98                 add(u, u + n, 1, 0);
 99             }else{
100                 add(u, u + n, 1, 0);
101             }
102         }
103         int ans = mincost(S, T);
104         cout<<ans<<endl;
105     }
106 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/8482908.html