POJ 3469 Dual Core CPU

来源:互联网 发布:淘宝在线考试答案 编辑:程序博客网 时间:2024/06/05 00:40

题目链接:http://poj.org/problem?id=3469

结合POJ 2987http://blog.csdn.net/u010489766/article/details/9301235

建图的话,这次没必要建二分图了,每个点都连接源点和汇点就行,源点和汇点就代表他的两个cpu核,一个任务不能在两个核上同时运行,所以要求最小割,即求最大流,

注意:这次两个任务之间的关系是个无向边,所以添边的时候反向边的权值不再是0了(我就WA在这了,%>_<%)

我的程序用dinic+vector的话6000+ms,略慢

#include<stdio.h>#include<string.h>#include<queue>#include<vector>#define min(x,y) x<y?x:y#define MEM(x,y) memset(x,y,sizeof(x))#define Max 100000000000#define INF 21000using namespace std;struct edge{int x,id,v;}e[30*INF];//有反向边,一定要开大点vector<int>vec[INF];//边的下标int n,m;int cnt,ans;int dis[INF];bool bfs(int start,int end){queue<int>Q;MEM(dis,-1);dis[start] = 0;Q.push(start);while(!Q.empty()){int temp = Q.front();Q.pop();int len = vec[temp].size();for(int i = 0 ; i < len ; i ++){int t = vec[temp][i];//下标if(e[t].v > 0 && dis[e[t].x] == -1){dis[e[t].x] = dis[temp] + 1;Q.push(e[t].x);}}}if(dis[end] >= 0)return true;elsereturn false;}int dfs(int x,int flow){if(x == n+1 || flow == 0)return flow;int len = vec[x].size();int dt = flow;//遍历到现在剩余的流量for(int i = 0 ; i < len ; i++){int t = vec[x][i];if(e[t].v > 0 && (dis[e[t].x] == dis[x] + 1) ){int a = dfs(e[t].x,min(e[t].v , dt));e[t].v -= a;e[e[t].id].v += a;dt -= a;if(dt == 0)break;}}return flow-dt;}void Dinic(int start,int end){while(bfs(start,end)){ans += dfs(start,Max);}}void addedge(int start,int end ,int v,int fan)//一种优化,如果(a,b,c)为无向边,那么就加入一个(a,b,c)和(b,a,c)就行了//并非(a,b,c),(b,a,0),(b,a,c)(a,b,0)四条边{e[cnt].v = v;e[cnt].x = end;e[cnt].id = cnt+1;vec[start].push_back(cnt);cnt++;e[cnt].v = fan;e[cnt].x = start;e[cnt].id = cnt-1;vec[end].push_back(cnt);cnt++;}int main(){while(scanf("%d%d",&n,&m) != EOF){MEM(e,0);for(int i = 0 ; i <= n+1;i++)vec[i].clear();cnt = 0;for(int i = 1; i <= n ; i ++){int a,b;scanf("%d%d",&a,&b);addedge(0,i,a,0);addedge(i,n+1,b,0);}for(int i = 1 ; i <= m ; i ++){int a,b,c;scanf("%d%d%d",&a,&b,&c);addedge(a,b,c,c);}ans = 0;Dinic(0,n+1);printf("%d\n",ans);}return 0;}


 

原创粉丝点击