View Code
1 #include//SAP 最大流应用 2 #include 3 #include 4 #include 5 #include 6 #include 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 ) 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<138 }*/ 139 if(sap(start,end,totals)==ans) 140 // cout<<"Case "< 141 //else cout<<"Case "< 142 // cout< 143 //cout< : 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 */144 cout<<"Case "< : Yes\n\n" ; 145 else cout<<"Case "<" "
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
其中涉及到三种优化,这一部分讲的特别好。
主要思路为:首先建立邻接表,然后建立层次图,查找最短最广路径。)
*/