hdu3572 最大流

来源:互联网 发布:视频人脸打马赛克软件 编辑:程序博客网 时间:2024/05/21 10:23

 

解题报告

题目 http://acm.hdu.edu.cn/showproblem.php?pid=3572

算法 :最大流

思路 :由于时间的范围只有500,因此可以用网络流来搞,关键点是每个任务只要在规定时间内完成即可,而且可在多个机器上,也就是说时间和机器能够不冲突的分配给每个任务就可以。也就是每个任务需要的时间在不冲突的情况下能否都被满足。源点向每个任务连一条流量为任务需要的时间的流,每个任务向他需要的实际那段的每个时刻连一个流量为1的边,每个时刻向汇点连一个流量为m的边即可。最后看最大流是否等于所有任务需要的总时间。

提交情况 wrong answer1次(输出格式错误)

                    Accepted 一次

收获和体会 :手生的摸了摸网络流,唉,都忘了。。。。。。 将时刻当作状态点的建图法还是不常见的,以后确定算法是在时间限制上也要多考虑考虑了。

ACcode

#include <stdio.h>

#include <string.h>

 

#define MAXE (500 * 500 * 10)

#define MAXN (5000)

#define BASE 500

#define rS 0

#define rT (500 + 501)

#define INF 0x77777777

 

struct EDGE{

   int to, flux, next;

}edges[MAXE];

inthead[MAXN], ad;

 

voidclear(){

   ad = 0;

   memset(head, -1, sizeof(head));

}

 

void insert(int u,int v, int flux){

   edges[ad].to = v, edges[ad].flux = flux, edges[ad].next = head[u],head[u] = ad ++;

   edges[ad].to = u, edges[ad].flux = 0,   edges[ad].next = head[v], head[v] = ad ++;

}

 

void Built(int n,int m, int &total){

   int len, st, end, i, j;

   total = 0;

   clear();

   for(i = 1; i <= n; i++){

      scanf("%d %d %d",&len, &st,&end);

      total += len;

      insert(rS, i, len);

      for(j = st; j <=end; j ++)

          insert(i, BASE + j, 1);

   }

   for(j = 1; j <= 500;j ++)

      insert(BASE + j, rT, m);

}

 

intqueue[MAXN], cur[MAXN], vis[MAXN],d[MAXN];

 

int bfs(int s,int t){

   int front = 0, tail = 1, u, v,p;

   memset(d, -1, sizeof(d));

   d[s] = 0;

   queue[0] = s;

   while(front <tail){

      u = queue[front ++];

      for(p = head[u]; ~p; p =edges[p].next){

          v = edges[p].to;

          if(edges[p].flux&& d[v] == -1){

             d[v] = d[u] + 1;

             queue[tail ++] = v;

          }

      }

   }

   return d[t] != -1;

}

 

int dfs(int x,int low){

   if(x == rT) return low;

   vis[x] = 1;

   for(int p = cur[x], temp, v; ~p; p = edges[p].next,cur[x] = p){

      v = edges[p].to;

      if(!vis[v], edges[p].flux&& d[v] == d[x] + 1)

          if(temp = dfs(v, low< edges[p].flux ? low : edges[p].flux)){

             edges[p].flux -= temp;

             edges[p ^ 1].flux += temp;

             return temp;

          }

   }

   return 0;

}

 

 

int dinic(int s,int t){

   int ans = 0, flow, i;

   while(bfs(s, t)){

      for(i = s; i <= t; i++) cur[i] = head[i];

      while(1){

          memset(vis, 0, sizeof(vis));

          if(!(flow = dfs(s, INF)))break;

          ans += flow;

      }

   }

   return ans;

}

 

int main(){

   int n, m, CASE, T, total,ans;

   scanf("%d",&CASE);

   for(T = 1; T <=CASE; T ++){

      scanf("%d %d",&n, &m);

      Built(n, m, total);

      ans = dinic(rS, rT);

      printf("Case %d: %s\n\n", T, ans== total ? "Yes" : "No");

   }

   return 0;

}