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 }
View Code

 

posted @ 2015-07-26 22:46  UsedRose  阅读(135)  评论(0编辑  收藏  举报