http://poj.org/problem?id=3469
题意:一台双核电脑,给你多个任务,分别给出每个任务在第一个核和第二个核上运行的消耗。后面的m行输入是给出两个任务在两个不同核上运行需要付出的额外消耗。
建图:把每个任务作为节点,在超级源点与任务间的连一条边,其容量为给任务在核1上运行的消耗,在该任务节点与超级汇点之间连一条边,容量为该任务在核2上运行的消耗。
在任务之间连接无向边,容量为两个任务不在同一核上运行的额外消耗。
搞了一天,ISPA 2S无压力 dinic看了各种版本的题解就只能到4S 不理解了 可能自己还有什么地方没考虑到吧
3469 | Accepted | 6184K | 2219MS | C++ | 2192B |
#include "stdio.h"
#include "queue"
#include "string.h"
#include "algorithm"
using namespace std;
const int maxn = 20020;
const int inf = 1<<30;
int n,pos;
int head[maxn];
struct node
{
int v,w,next;
node(){}
node( int v,int w,int next ):v(v),w(w),next(next){}
}edge[30*maxn];
void add( int u,int v,int w,int ww )
{
edge[pos].v = v; edge[pos].w = w; edge[pos].next = head[u];
head[u] = pos++;
edge[pos].v = u; edge[pos].w = ww; edge[pos].next = head[v];
head[v] = pos++;
}
int SAP_Max_Flow( int st,int end )
{
int cur[maxn],pre[maxn],h[maxn],gap[maxn];
int u,neck,tmp,i;
memset( h,0,sizeof(h) );
memset( gap,0,sizeof(gap) );
int cur_flow,flow_ans = 0;
for( int i = 0; i <= n; i ++ )
cur[i] = head[i];
gap[0] = n+1;
u = st;
while( h[st] < n+1 )
{
if( u == end )
{
cur_flow = inf;
for( i = st; i != end; i = edge[cur[i]].v )
{
if( cur_flow > edge[cur[i]].w )
{
neck = i;
cur_flow = edge[cur[i]].w;
}
}
for( i = st; i != end; i = edge[cur[i]].v )
{
tmp = cur[i];
edge[tmp].w -= cur_flow;
edge[tmp^1].w += cur_flow;
}
flow_ans += cur_flow;
u = neck;
}
for( i = cur[u]; i != -1; i = edge[i].next )
{
if( edge[i].w && h[u] == h[edge[i].v] + 1 )
break;
}
if( i != -1 )
{
cur[u] = i;
pre[edge[i].v] = u;
u = edge[i].v;
}
else
{
if( 0 == --gap[h[u]] )
break;
cur[u] = head[u];
for( tmp = n,i = head[u]; i != -1; i = edge[i].next )
if( edge[i].w )
tmp = tmp < h[edge[i].v]?tmp:h[edge[i].v];
h[u] = tmp + 1;
gap[h[u]] ++;
if( u != st )
u = pre[u];
}
}
return flow_ans;
}
int main()
{
//freopen("data.txt","r",stdin);
int nt,m,a,b,c;
while( scanf("%d%d",&nt,&m) == 2 )
{
pos = 0;
n = nt + 1;
for( int i = 0; i <= n; i ++ )
head[i] = -1;
for( int i = 1; i <= nt; i ++ )
{
scanf("%d%d",&a,&b);
add(0,i,a,0);
add(i,n,b,0);
}
for( int i = 1; i <= m; i ++ )
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c,c);
}
printf("%d\n",SAP_Max_Flow(0,n));
}
return 0;
}
3469 | Accepted | 6188K | 4438MS | C++ | 2014B |
#include "stdio.h"
#include "queue"
#include "string.h"
#include "algorithm"
using namespace std;
const int maxn = 20020;
const int inf = 1<<30;
int n,pos;
int head[maxn],dis[maxn];
struct node
{
int v,w,next;
node(){}
node( int v,int w,int next ):v(v),w(w),next(next){}
}edge[30*maxn];
void add( int u,int v,int w,int ww )
{
edge[pos].v = v; edge[pos].w = w; edge[pos].next = head[u];
head[u] = pos++;
edge[pos].v = u; edge[pos].w = ww; edge[pos].next = head[v];
head[v] = pos++;
}
int mins( int a,int b )
{
return a < b?a:b;
}
bool Dinic_bfs( int st )
{
queue<int>que;
for( int i = 0; i <= n; i ++ )
dis[i] = -1;
dis[st] = 0;
que.push(st);
while( !que.empty() ){
int u = que.front(); que.pop();
for( int i = head[u]; i != -1; i = edge[i].next ){
node v = edge[i];
if( v.w && dis[v.v] == -1 ){
dis[v.v] = dis[u] + 1;
que.push(v.v);
if( v.v == n )
return true;
}
}
}
return false;
}
int Dinic_dfs( int u,int maxf )
{
if( u == n )
return maxf;
int ans = 0, flow;
for( int i = head[u]; i != -1 && ans < maxf; i = edge[i].next ){
if( edge[i].w && dis[edge[i].v] == dis[u] + 1 ){
if( flow = Dinic_dfs( edge[i].v,mins(edge[i].w,maxf-ans) )){
edge[i].w -= flow;
edge[i^1].w += flow;
ans += flow;
}
}
}
if( !ans )//关键的一句话
dis[u] = -1;
return ans;
}
int Dinic( int st,int end )
{
int ans = 0,flow;
while( Dinic_bfs(st) ){
while( flow = Dinic_dfs( st,inf ) ) //增广
ans += flow;
}
return ans;
}
int main()
{
//freopen("data.txt","r",stdin);
int nt,m,a,b,c;
while( scanf("%d%d",&nt,&m) == 2 )
{
int s = 0;
pos = 0;
n = nt + 1;
for( int i = 0; i <= n; i ++ )
head[i] = -1;
for( int i = 1; i <= nt; i ++ )
{
scanf("%d%d",&a,&b);
add(0,i,a,0);
add(i,n,b,0);
}
for( int i = 1; i <= m; i ++ )
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c,c);
}
printf("%d\n",Dinic(s,n));
}
return 0;
}
3469 | Accepted | 6256K | 4204MS | C++ | 2005B |
#include "stdio.h"
#include "queue"
#include "string.h"
#include "algorithm"
using namespace std;
const int maxn = 20020;
const int inf = 1<<30;
int n,pos;
int head[maxn],cur[maxn],dis[maxn];
struct node
{
int v,w,next;
node(){}
node( int v,int w,int next ):v(v),w(w),next(next){}
}edge[30*maxn];
void add( int u,int v,int w,int ww )
{
edge[pos].v = v; edge[pos].w = w; edge[pos].next = head[u];
head[u] = pos++;
edge[pos].v = u; edge[pos].w = ww; edge[pos].next = head[v];
head[v] = pos++;
}
int mins( int a,int b )
{
return a < b?a:b;
}
bool Dinic_bfs( int st )
{
queue<int>que;
for( int i = 0; i <= n; i ++ )
dis[i] = -1;
dis[st] = 0;
que.push(st);
while( !que.empty() ){
int u = que.front(); que.pop();
for( int i = head[u]; i != -1; i = edge[i].next ){
node v = edge[i];
if( v.w && dis[v.v] == -1 ){
dis[v.v] = dis[u] + 1;
que.push(v.v);
if( v.v == n )
return true;
}
}
}
return false;
}
int Dinic_dfs( int u,int maxf )
{
if( u == n )
return maxf;
int ans = 0, flow;
for( int &i = cur[u]; i != -1 && ans < maxf; i = edge[i].next ){
if( edge[i].w && dis[edge[i].v] == dis[u] + 1 ){
if( flow = Dinic_dfs( edge[i].v,mins(edge[i].w,maxf-ans) )){
edge[i].w -= flow;
edge[i^1].w += flow;
return flow;
}
}
}
return 0;
}
int Dinic( int st,int end )
{
int ans = 0,flow;
while( Dinic_bfs(st) ){
memcpy(cur,head,sizeof(head));
while( flow = Dinic_dfs( st,inf ) ) //增广
ans += flow;
}
return ans;
}
int main()
{
//freopen("data.txt","r",stdin);
int nt,m,a,b,c;
while( scanf("%d%d",&nt,&m) == 2 )
{
pos = 0;
n = nt + 1;
for( int i = 0; i <= n; i ++ )
head[i] = -1;
for( int i = 1; i <= nt; i ++ )
{
scanf("%d%d",&a,&b);
add(0,i,a,0);
add(i,n,b,0);
}
for( int i = 1; i <= m; i ++ )
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c,c);
}
printf("%d\n",Dinic(0,n));
}
return 0;
}
3469 | Accepted | 6112K | 2844MS | C++ | 2376B |
#include <iostream>
using namespace std;
const int nMax = 20030;
const int mMax = 230000;
const int inf = 0x7fffffff;
int head[nMax], temp[nMax];
int que[nMax], level[nMax];
int ne;
struct Edge
{
int v, c, next;
} edges[2*(nMax+mMax)];
void addEdges(int from, int to, int val1, int val2)
{
edges[ne].v = to;
edges[ne].c = val1;
edges[ne].next = head[from];
head[from] = ne++;
edges[ne].v = from;
edges[ne].c = val2;
edges[ne].next = head[to];
head[to] = ne++;
}
int Dinic(int sta, int end)
{
int max = 0;
int i, k, curr;
while(true)
{
memset(level, -1, sizeof(level));
int f, r;
f = 0; r = 1;
que[0] = sta;
level[sta] = 0;
while(f < r)
{
curr = que[f++];
for(i = head[curr]; i; i = edges[i].next)
if(edges[i].c && level[k = edges[i].v] == -1)
{
level[k] = level[curr] + 1;
que[r++] = k;
if(k == end){ f = r; break; }
}
}
if(level[end] == -1) break;
memcpy(temp, head, sizeof(temp));
int top;
for(curr = sta, top = 0; ;)
{
if(curr == end)
{
int tp = inf;
for(i = 0; i < top; i++)
if(tp > edges[que[i]].c)
tp = edges[que[f = i]].c;
for(i = 0; i < top; i++)
{
edges[que[i]].c -= tp;
edges[que[i]^1].c += tp;
}
top = f;
max += tp; curr = edges[que[top-1]].v;
}
for(i = temp[curr]; temp[curr]; i = temp[curr] = edges[temp[curr]].next)
if(edges[i].c && level[edges[i].v] == level[curr] + 1)
break;
if(temp[curr])
{
que[top++] = temp[curr];
curr = edges[temp[curr]].v;
}
else
{
if(top == 0) break;
level[curr] = -1;
if((top--) == 1)
curr = sta;
else
curr = edges[head[top-1]].v;
}
}
}
return max;
}
int main()
{
int n, m;
int k, j, val1, val2;
int i;
//freopen("a.txt", "r", stdin);
ne = 2;
memset(head, 0, sizeof(head));
scanf("%d%d", &n, &m);
for(i = 1; i <= n; i++)
{
scanf("%d%d", &val1, &val2);
addEdges(0, i, val1, 0);
addEdges(i, n+1, val2, 0);
}
for(i = 1; i <= m; i++)
{
scanf("%d%d%d", &k, &j, &val1);
addEdges(k, j, val1, val1);
}
printf("%d\n", Dinic(0, n+1));
return 0;
}
3469 | Accepted | 6148K | 3469MS | C++ | 2045B |
#include<cstdio>
using namespace std;
const int mm=1000000;
const int mn=22222;
const int oo=1000000000;
int node,src,dest,edge;
int reach[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn];
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void prepare(int _node,int _src,int _dest)
{
node=_node,src=_src,dest=_dest;
for(int i=0;i<node;++i)head[i]=-1;
edge=0;
}
inline void addedge(int u,int v,int c1,int c2)
{
reach[edge]=v,flow[edge]=c1,next[edge]=head[u],head[u]=edge++;
reach[edge]=u,flow[edge]=c2,next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
int i,u,v,l,r=0;
for(i=0;i<node;++i)dis[i]=-1;
dis[q[r++]=src]=0;
for(l=0;l<r;++l)
for(i=head[u=q[l]];i>=0;i=next[i])
if(flow[i]&&dis[v=reach[i]]<0)
{
dis[q[r++]=v]=dis[u]+1;
if(v==dest)return 1;
}
return 0;
}
int Dinic_dfs(int u,int exp)
{
if(u==dest)return exp;
for(int &i=work[u],v,tmp;i>=0;i=next[i])
if(flow[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
{
flow[i]-=tmp;
flow[i^1]+=tmp;
return tmp;
}
return 0;
}
int Dinic_flow()
{
int i,ret=0,delta;
while(Dinic_bfs())
{
for(i=0;i<node;++i)work[i]=head[i];
while(delta=Dinic_dfs(src,oo))ret+=delta;
}
return ret;
}
int main()
{
int i,j,n,m,a,b;
while(scanf("%d%d",&n,&m)!=-1)
{
prepare(n+2,0,n+1);
for(i=1;i<=n;++i)
{
scanf("%d%d",&a,&b);
addedge(src,i,a,0);
addedge(i,dest,b,0);
}
while(m--)
{
scanf("%d%d%d",&i,&j,&a);
addedge(i,j,a,a);
}
printf("%d\n",Dinic_flow());
}
return 0;
}