Hdu Task Schedule

View Code
  1 #include <iostream>//SAP 最大流应用
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 #define min(a,b) ((a)<(b))?(a):(b)
  9 #define max(a,b) ((a)>(b))?(a):(b)
 10 #define MAXN 1111+10
 11 #define MAXM 505000+10//M取N的平方倍
 12 #define INF 0x3f3f3f3f
 13 
 14 //链式前向星
 15 struct enode
 16 {
 17     int t;
 18     int w;                //权值
 19     int c;                //流量
 20 //  int cost;
 21 //    int pre;            //前向指针
 22     int next;
 23 };
 24 
 25 
 26     struct enode e[MAXM];
 27     int box[MAXN],ecnt;
 28     //int etail[MAXN];        //尾部
 29     void init()
 30     {
 31         ecnt=0;
 32         memset(box,-1,sizeof(box));
 33     //    memset(etail,-1,sizeof(etail));        //初始化尾部
 34     }
 35     void addedge(int f,int t,int c)            //流量重载
 36     {
 37         e[ecnt].next=box[f];
 38         e[ecnt].t=t;
 39         e[ecnt].c=c;
 40         box[f]=ecnt++;
 41         e[ecnt].next=box[t];
 42         e[ecnt].t=f;
 43         e[ecnt].c=0;
 44         box[t]=ecnt++;
 45     }
 46 int sap(int s,int t,int N)//最大流问题
 47 {
 48     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
 49     int curflow,ans=0,u,tmp,neck,i;
 50     memset(lvl,0,sizeof(lvl));
 51     memset(gap,0,sizeof(gap));
 52     memset(pre,-1,sizeof(pre));
 53     for(i=0;i<N;i++)
 54         cur[i]=box[i];
 55     gap[0]=N;
 56     u=s;
 57     while(lvl[s]<N)
 58     {
 59         if(u==t)
 60         {
 61             curflow=INF;
 62             for(i=s;i!=t;i=e[cur[i]].t)
 63             {
 64                 if(curflow>e[cur[i]].c)
 65                 {
 66                     neck=i;
 67                     curflow=e[cur[i]].c;
 68                 }
 69             }
 70             for(i=s;i!=t;i=e[cur[i]].t)
 71             {
 72                 tmp=cur[i];
 73                 e[tmp].c-=curflow;
 74                 e[tmp^1].c+=curflow;
 75             }
 76             ans+=curflow;
 77             u=neck;
 78         }
 79         for(i=cur[u];i!=-1;i=e[i].next)
 80             if(e[i].c && lvl[u]==lvl[e[i].t]+1)
 81                 break;
 82         if(i!=-1)
 83         {
 84             cur[u]=i;
 85             pre[e[i].t]=u;
 86             u=e[i].t;
 87         }
 88         else
 89         {
 90             if(--gap[lvl[u]]==0)
 91                 break;
 92              cur[u]=box[u];
 93             for(tmp=N,i=box[u];i!=-1;i=e[i].next)
 94                 if(e[i].c)
 95                     tmp=min(tmp,lvl[e[i].t]);
 96             lvl[u]=tmp+1;
 97             gap[lvl[u]]++;
 98             if(u!=s)
 99                 u=pre[u];
100         }
101     }
102     return ans;
103 }
104 int main()
105 {
106       int m,n,i,j,t;
107       scanf("%d",&t);
108       int ct=1;
109         while(t--)
110         {
111             int pi,si,ei;
112             int start,end,totals,max,ans;//起点/汇点/总网络结点/最大ei/总天数
113             start=max=ans=0;
114             cin>>n>>m;
115            // memset(map,0,sizeof(map));
116             init();
117             for(i=1;i<=n;i++)
118             {
119                 cin>>pi>>si>>ei;
120                 addedge(start,i,pi);
121                 max=max>ei?max:ei;
122                 ans+=pi;
123                 for(j=si;j<=ei;j++)
124                 {
125                     addedge(i,n+j,1);
126                 }//任务&每天:每天只能处理一个任务
127             }//参数含义:源点 汇点 网络结点数量*/
128             end=1+max+n;
129             totals=end+1;
130             for(i=1;i<=max;i++)
131             {
132                 addedge(n+i,end,m);
133             }
134       /*  for(int i=1;i<=totals;i++)
135         {
136             for(int k=box[i];k!=-1;k=e[k].next)
137                 cout<<i<< " " <<e[k].t<< " " <<e[k].c<<endl;
138         }*/
139             if(sap(start,end,totals)==ans)
140         //    cout<<"Case "<<ct++<<":"<<" Yes\n\n";
141        //else cout<<"Case "<<ct++<<":"<<" No\n\n";
142       // cout<<sap(start,end,totals)<<endl;
143             //cout<<endl;
144              cout<<"Case "<<ct++<<": Yes\n\n" ;
145         else cout<<"Case "<<ct++<<": No\n\n" ;
146         }
147     return 0;
148 }
149 /*
150 Sample Input
151 
152 2
153 4 3
154 1 3 5
155 1 1 4
156 2 3 7
157 3 5 9
158 2 2
159 2 1 3
160 1 2 2
161 
162 Sample Output
163 
164 Case 1: Yes
165 
166 Case 2: Yes
167 
168 */

http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1003&ojid=0&cid=4456&hide=0

/*
题意:用m个机器,处理n个任务,每个任务必须在[si,ei]时间段完成,需要pi天才能完成。每个机器只能处理一个任务,
即每天只能处理m个任务。
题解: 采用最大流,
建图:把每个任务和每一天看做一个点,增加源点s和汇点t,在s和每个任务之间连一条边,容量为持续
天数;在每一天和t之间连一条边,容量为m;在每个任务和对应天数之间连一条边,容量为1。然后最大流量即为所求。
实现:sap算法
(网上提到 关于sap详细介绍参见:http://chuanwang66.iteye.com/blog/1450715
其中涉及到三种优化,这一部分讲的特别好。
主要思路为:首先建立邻接表,然后建立层次图,查找最短最广路径。)

*/

posted on 2013-04-18 23:01  ACM_Someone like you  阅读(252)  评论(0编辑  收藏  举报

导航