zoj 月赛
E题
1 /*Author :usedrose */ 2 /*Created Time :2015/7/26 22:29:35*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define OK cout << "ok" << endl; 24 #define o(a) cout << #a << " = " << a << endl 25 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 26 using namespace std; 27 typedef long long LL; 28 29 //最小费用最大流,求最大费用只需要取相反数,结果取相反数即可。 30 //点的总数为 N,点的编号 0~N-1 31 const int MAXN = 10000; 32 const int MAXM = 100000; 33 34 int n,m; 35 36 int A[MAXN],B[MAXN],X[MAXN],Y[MAXN]; 37 38 struct Edge 39 { 40 int to,next,cap,flow,cost; 41 }edge[MAXM]; 42 int head[MAXN],tol; 43 int pre[MAXN],dis[MAXN]; 44 bool vis[MAXN]; 45 int N;//节点总个数,节点编号从0~N-1 46 47 void init(int n) 48 { 49 N = n; 50 tol = 0; 51 memset(head,-1,sizeof(head)); 52 } 53 54 void addedge(int u,int v,int cap,int cost) 55 { 56 edge[tol].to = v; 57 edge[tol].cap = cap; 58 edge[tol].cost = cost; 59 edge[tol].flow = 0; 60 edge[tol].next = head[u]; 61 head[u] = tol++; 62 edge[tol].to = u; 63 edge[tol].cap = 0; 64 edge[tol].cost = -cost; 65 edge[tol].flow = 0; 66 edge[tol].next = head[v]; 67 head[v] = tol++; 68 } 69 70 bool spfa(int s,int t) 71 { 72 queue<int>q; 73 for(int i = 0;i < N;i++) 74 { 75 dis[i] = INF; 76 vis[i] = false; 77 pre[i] = -1; 78 } 79 dis[s] = 0; 80 vis[s] = true; 81 q.push(s); 82 while(!q.empty()) 83 { 84 int u = q.front(); 85 q.pop(); 86 vis[u] = false; 87 for(int i = head[u]; i != -1;i = edge[i].next) 88 { 89 int v = edge[i].to; 90 if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) 91 { 92 dis[v] = dis[u] + edge[i].cost; 93 pre[v] = i; 94 if(!vis[v]) 95 { 96 vis[v] = true; 97 q.push(v); 98 } 99 } 100 } 101 } 102 if(pre[t] == -1) return false; 103 else return true; 104 } 105 106 //返回的是最大流, cost存的是最小费用 107 int minCostMaxflow(int s,int t,int &cost) 108 { 109 int flow = 0; 110 cost = 0; 111 while(spfa(s,t)) 112 { 113 int Min = INF; 114 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 115 { 116 if(Min > edge[i].cap - edge[i].flow) 117 Min = edge[i].cap - edge[i].flow; 118 } 119 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 120 { 121 edge[i].flow += Min; 122 edge[i^1].flow -= Min; 123 cost += edge[i].cost * Min; 124 } 125 flow += Min; 126 } 127 return flow; 128 } 129 130 131 int main() 132 { 133 //freopen("data.in","r",stdin); 134 //freopen("data.out","w",stdout); 135 cin.tie(0); 136 ios::sync_with_stdio(false); 137 while (cin >> n >> m) { 138 int all = 0; 139 init(n+2); 140 int s = 0, t = n+1; 141 for (int i = 1;i <= n; ++ i) { 142 cin >> A[i] >> B[i]; 143 if (A[i] > B[i]) 144 addedge(s, i, A[i]-B[i], 0); 145 else if (A[i] < B[i]) { 146 addedge(i, t, B[i]-A[i], 0); 147 all += (B[i] - A[i]); 148 } 149 } 150 int u, v; 151 for (int i = 0;i < m; ++ i) { 152 cin >> u >> v; 153 addedge(u, v, INF, 1); 154 addedge(v, u, INF, 1); 155 } 156 int cost, ans; 157 ans = minCostMaxflow(s, t, cost); 158 if (ans < all) cout << -1 << endl; 159 else cout << cost << endl; 160 } 161 return 0; 162 }