双核CPU还行...
题意:
给定n个任务 由a核和b核完成分别需要ai,bi花费
同时m个约束形如(x,y,w) 如果x,y不在一个核上就额外花费w 求最小花费
Solution:
一开始想的拆点...最后发现图不连通
其实这个每个点向两边分别连ai,bi就行 因为流取得就是路径上所有边的最小值
没错就是源汇分别表示A,B
求一个最小割表示最小花费
约束的话就连一个双向边
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<iostream> 5 #include<algorithm> 6 #define ms(a,b) memset(a,b,sizeof a) 7 #define rep(i,a,n) for(int i = a;i <= n;i++) 8 #define per(i,n,a) for(int i = n;i >= a;i--) 9 #define inf 2147483647 10 using namespace std; 11 typedef long long ll; 12 typedef double D; 13 #define eps 1e-8 14 ll read() { 15 ll as = 0,fu = 1; 16 char c = getchar(); 17 while(c < '0' || c > '9') { 18 if(c == '-') fu = -1; 19 c = getchar(); 20 } 21 while(c >= '0' && c <= '9') { 22 as = as * 10 + c - '0'; 23 c = getchar(); 24 } 25 return as * fu; 26 } 27 const int N = 20005; 28 const int M = 900005; 29 //head 30 int s = N-2,t = N-1; 31 int head[N],nxt[M],mo[M],cst[M],cnt = 1; 32 void _add(int x,int y,int w) { 33 mo[++cnt] = y; 34 cst[cnt] = w; 35 nxt[cnt] = head[x]; 36 head[x] = cnt; 37 } 38 void add(int x,int y,int w) { 39 if(x^y) _add(x,y,w),_add(y,x,0); 40 } 41 42 int dep[N],cur[N]; 43 bool bfs() { 44 queue<int> q; 45 memcpy(cur,head,sizeof cur); 46 ms(dep,0),q.push(s),dep[s] = 1; 47 while(!q.empty()) { 48 int x = q.front(); 49 q.pop(); 50 for(int i = head[x];i;i = nxt[i]) { 51 int sn = mo[i]; 52 if(!dep[sn] && cst[i]) { 53 dep[sn] = dep[x] + 1; 54 q.push(sn); 55 } 56 } 57 } 58 return dep[t]; 59 } 60 61 int dfs(int x,int flow) { 62 if(x == t || flow == 0) return flow; 63 int res = 0; 64 for(int &i = cur[x];i;i = nxt[i]) { 65 int sn = mo[i]; 66 if(dep[sn] == dep[x] + 1 && cst[i]) { 67 int d = dfs(sn,min(cst[i],flow - res)); 68 if(d) { 69 cst[i] -= d,cst[i^1] += d; 70 res += d; 71 if(res == flow) break; 72 } 73 } 74 } 75 if(res ^ flow) dep[x] = 0; 76 return res; 77 } 78 79 int DINIC() { 80 int ans = 0; 81 while(bfs()) ans += dfs(s,inf); 82 return ans; 83 } 84 85 int n,m; 86 87 int main() { 88 n = read(),m = read(); 89 rep(i,1,n) { 90 add(s,i,read()); 91 add(i,t,read()); 92 } 93 rep(i,1,m) { 94 int x = read(),y = read(),w = read(); 95 add(x,y,w),add(y,x,w); 96 } 97 printf("%d ",DINIC()); 98 return 0; 99 }