HDU 3572 网络源
HDU 3572 网络流
题意:
n个任务, m台机器(每台机器每天只能执行一个任务) 任务可以不连续执行,可以让别的机器交替执行
下面n行
need st en 表示任务需要在 [st, en]之间完成,需要need天 (保证 en - st+1 >=need )
问能否全部执行完
思路:
0为源点,1-n为n个任务 (源点到天数边权值为 need)
n+1 - n+1+Maxday 为天数
每个任务到 [st, en]建权值为1的边
每个任务到汇点建权值为m的边
#include<string.h> #include<stdio.h> #include<queue> #define M 1505 #define inf 33554432 using namespace std; inline int Max(int a,int b){return a<b?b:a;} inline int Min(int a,int b){return a>b?b:a;} struct Edge{ int from, to, cap, nex; }edge[M*M]; int head[M*4], edgenum; void addedge(int u, int v, int cap){ Edge E = { u, v, cap, head[u]}; edge[ edgenum ] = E; head[u] = edgenum ++; } int sign[M*4], s, t; bool BFS(int from, int to){ memset(sign, -1, sizeof(sign)); sign[from] = 0; queue<int>q; q.push(from); while( !q.empty() ){ int u = q.front(); q.pop(); for(int i = head[u]; i!=-1; i = edge[i].nex) { int v = edge[i].to; if(sign[v]==-1 && edge[i].cap) { sign[v] = sign[u] + 1, q.push(v); if(sign[to] != -1)return true; } } } return false; } int Stack[M*4], top, cur[M*4]; int day; int dinic(){ int ans = 0; while( BFS(s, t) ) { memcpy(cur, head, sizeof(head)); int u = s; top = 0; while(1) { if(u == t) { int flow = inf, loc;//loc 表示 Stack 中 cap 最小的边 for(int i = 0; i < top; i++) if(flow > edge[ Stack[i] ].cap) { flow = edge[Stack[i]].cap; loc = i; } for(int i = 0; i < top; i++) { edge[ Stack[i] ].cap -= flow; edge[Stack[i]^1].cap += flow; } ans += flow; top = loc; u = edge[Stack[top]].from; } for(int i = cur[u]; i!=-1; cur[u] = i = edge[i].nex)//cur[u] 表示u所在能增广的边的下标 if(edge[i].cap && (sign[u] + 1 == sign[ edge[i].to ]))break; if(cur[u] != -1) { Stack[top++] = cur[u]; u = edge[ cur[u] ].to; } else { if( top == 0 )break; sign[u] = -1; u = edge[ Stack[--top] ].from; } } } return ans == day; } void Have_map(int n, int m){ day = 0; memset(head, -1, sizeof(head)); edgenum = 0; int i, j; int st, need, en, Maxday = 1; for(i = 1; i <= n; i++) { scanf("%d %d %d",&need,&st,&en); addedge(s, i, need); addedge(i, s, 0 ); day += need; for(j = st; j <= en; j++) { addedge(i, n + 1 + j, 1); addedge(n + 1 + j, i, 0); } Maxday = Max(Maxday, en); } t = n + Maxday + 10; for(i = 1; i <= Maxday; i++) { addedge(n+i+1, t, m); addedge(t, n+i+1, 0); } } int main(){ int n, m, T, Cas = 1;scanf("%d",&T); s = 0; while(T--) { scanf("%d %d", &n, &m); Have_map(n, m); printf("Case %d: ",Cas++); if(dinic()) printf("Yes\n\n"); else printf("No\n\n"); } return 0; }