建图,源点为A核,汇点为B核,每个顶点有A-> i -> B的两条边。
如果两个顶点不是同一个核需要代价,这两个点建立两条有向边。
相当于求最小割,呃,就是求最大流了 = =。。。刚想明白。。。最小割就是最大流啊。。。
我的dinic模板TLE了 = =。。
搜的一个模板4000+MS过了 = =。。。
哎。。又要好好理解咧。。。
#include <cstdio> #include <cstdlib> #include <iostream> #include <string.h> #include <queue> #include <limits.h> #define MAX 20010 using namespace std; typedef struct NODE{ int u,v,cap; int next; }NODE; NODE node[MAX*50]; int cpu[MAX],cou; int n,m; int lev[MAX]; void init() { cou = 2; memset(node,'/0',sizeof(node)); memset(cpu,-1,sizeof(cpu)); } void Add(int u,int v,int cap) { node[cou].u = u; node[cou].v = v; node[cou].cap = cap; node[cou].next = cpu[u]; cpu[u] = cou++; node[cou].u = v; node[cou].v = u; node[cou].cap = 0; node[cou].next = cpu[v]; cpu[v] = cou++; } queue<int> q; int BFS(int s,int t) { int u,v,head,cap; memset(lev,-1,sizeof(lev)); q.push(s); lev[s] = 0; while( !q.empty() ) { u = q.front(); q.pop(); head = cpu[u]; while( head != -1 ) { cap = node[head].cap; v = node[head].v; if( cap > 0 && lev[v] == -1 ) { lev[v] = lev[u] + 1; q.push(v); } head = node[head].next; } } return lev[t] != -1; } int que[MAX*10]; int Dinic(int n, int s, int t) { int flow = 0, ag, i,cur[MAX],head,cap,v; while( BFS(s, t) ) { int u = s, tail = 0; for(i = 0; i < n; i++) cur[i] = cpu[i]; while(cur[s] != -1) { head = cur[u]; cap = node[head].cap; v = node[head].v; if (u != t && cur[u] != -1 && cap > 0 && lev[u] != -1 && lev[u] + 1 == lev[v]) { que[tail++] = cur[u]; u = v; } else if (u == t) { ag = INT_MAX; for(i=tail-1; i>=0; i--) ag = min(ag, node[que[i]].cap); flow += ag; for(i=tail-1; i>=0; i--) { node[que[i]].cap -= ag; node[que[i] ^ 1].cap += ag; if (node[que[i]].cap == 0) tail = i; } u = node[que[tail]].u; } else { while( tail > 0 && u != s && cur[u] == -1 ) u = node[que[--tail]].u; cur[u] = node[cur[u]].next; } } } return flow; } int main() { int i,capa,capb,cap,from,to,ans; while( ~scanf("%d%d",&n,&m) ) { init(); for(i=1; i<=n; i++) { scanf("%d%d",&capa,&capb); Add(0,i,capa); Add(i,n+1,capb); } while( m-- ) { scanf("%d%d%d",&from,&to,&cap); Add(from,to,cap); Add(to,from,cap); } ans = Dinic(n+2,0,n+1); printf("%d/n",ans); } return 0; }