【HDOJ】2853 Assignment

最小费用最大流可解最优解。至于dif如何解,可以把w扩大100倍,如果mission编号和排列P相等则对w+1,然后建立网络流。
对结果取模100可以得到没有改变mission的company数目,用company数目减之可以得到dif.

  1 /* 2853 */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23 
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41 
 42 const int INF = 0x1f1f1f1f;
 43 const int maxn = 55;
 44 const int maxv = maxn * 2;
 45 const int maxe = maxv * maxv * 5;
 46 int V[maxe], F[maxe], W[maxe], nxt[maxe];
 47 int head[maxv], dis[maxv], pre[maxv], ID[maxv];
 48 bool visit[maxv];
 49 int M[maxn][maxn], P[maxn];
 50 int s, t, m;
 51 
 52 void addEdge(int u, int v, int f, int w) {
 53     V[m] = v;
 54     F[m] = f;
 55     W[m] = w;
 56     nxt[m] = head[u];
 57     head[u] = m++;
 58     
 59     V[m] = u;
 60     F[m] = 0;
 61     W[m] = -w;
 62     nxt[m] = head[v];
 63     head[v] = m++;
 64 }
 65 
 66 bool bfs() {
 67     queue<int> Q;
 68     int u, v, k;
 69     
 70     memset(dis, INF, sizeof(dis));
 71     memset(visit, false, sizeof(visit));
 72     Q.push(s);
 73     dis[s] = 0;
 74     
 75     while (!Q.empty()) {
 76         u = Q.front();
 77         Q.pop();
 78         visit[u] = false;
 79         for (k=head[u]; k!=-1; k=nxt[k]) {
 80             v = V[k];
 81             if (F[k] && dis[v]>dis[u]+W[k]) {
 82                 dis[v] = dis[u] + W[k];
 83                 ID[v] = k;
 84                 pre[v] = u;
 85                 if (!visit[v]) {
 86                     visit[v] = true;
 87                     Q.push(v);
 88                 }
 89             }
 90         }
 91     }
 92     
 93     return dis[t]==INF;
 94 }
 95 
 96 int MCMF() {
 97     int ret = 0, tmp;
 98     int u, v, k;
 99     
100     while (1) {
101         if (bfs())
102             break;
103         
104         tmp = INF;
105         for (v=t, u=pre[v]; v!=s; v=u, u=pre[v]) {
106             k = ID[v];
107             tmp = min(F[k], tmp);
108         }
109         
110         for (v=t, u=pre[v]; v!=s; v=u, u=pre[v]) {
111             k = ID[v];
112             F[k] -= tmp;
113             F[k^1] += tmp;
114         }
115         
116         ret += dis[t] * tmp;
117     }
118     
119     return ret;
120 }
121 
122 
123 int main() {
124     ios::sync_with_stdio(false);
125     #ifndef ONLINE_JUDGE
126         freopen("data.in", "r", stdin);
127         freopen("data.out", "w", stdout);
128     #endif
129     
130     int r, c;
131     int ans, tot, tmp, dif;
132     
133     while (scanf("%d %d", &r, &c) != EOF) {
134         
135         s = m = 0;
136         t = r + c + 1;
137         memset(head, -1, sizeof(head));
138         
139         rep(i, 1, r+1)
140             rep(j, 1, c+1)
141                 scanf("%d", &M[i][j]);
142         rep(i, 1, r+1)        
143             scanf("%d", &P[i]);
144             
145         rep(i, 1, r+1)
146             addEdge(s, i, 1, 0);
147             
148         rep(j, 1, c+1)
149             addEdge(j+r, t, 1, 0);
150         
151         tot = 0;
152         rep(i, 1, r+1) {
153             rep(j, 1, c+1) {
154                 if (j == P[i]) {
155                     tmp = M[i][j] * 100 + 1;
156                 } else {
157                     tmp = M[i][j] * 100;
158                 }
159                 addEdge(i, j+r, 1, -tmp);
160             }
161             tot += M[i][P[i]];
162         }
163         
164         tmp = -MCMF();
165         ans = tmp/100 - tot;
166         #ifndef ONLINE_JUDGE
167             printf("tot = %d, MCMF = %d\n", tot, tmp);
168         #endif
169         dif = r - tmp%100;
170         printf("%d %d\n", dif, ans);
171     }
172     
173     #ifndef ONLINE_JUDGE
174         printf("time = %d.\n", (int)clock());
175     #endif
176     
177     return 0;
178 }

 

posted on 2015-10-17 16:19  Bombe  阅读(160)  评论(0编辑  收藏  举报

导航