HDU 3572——Task Schedule

来源:互联网 发布:收据打印软件 注册码 编辑:程序博客网 时间:2024/04/30 02:42

最大流问题 

Dinic算法

#include <iostream>#include<cstdio>#include<cstring>#include<cstdio>#include<queue>#include<vector>using namespace std;const int maxint=1000001;int n,m,s,t;struct edgee{int from,to,cap,flow;};vector<edgee> edges;vector<int> G[1003];bool vis[1003];int dist[1003];int cur[1003];void add(int from,int to,int cap){edges.push_back((edgee){from,to,cap,0});edges.push_back((edgee){to,from,0,0});int k=edges.size();G[from].push_back(k-2);//偶数数为正向弧 G[to].push_back(k-1);}int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}bool bfs(){memset(vis,0,sizeof(vis));queue<int> q;dist[s]=0;vis[s]=1;q.push(s);while(!q.empty()){int u=q.front();q.pop();int sz=G[u].size();for(int i=0;i<sz;i++){edgee& e=edges[G[u][i]];if(!vis[e.to] && e.cap>e.flow){vis[e.to]=1;dist[e.to]=dist[u]+1;q.push(e.to);}}}return vis[t];}int dfs(int u,int low){if(u==t || low==0)return low;int flow=0,sz=G[u].size(),d;//&引用的妙用for(int& i=cur[u];i<sz;i++) //正在考虑的最后一条边开始考虑(效率关键){edgee& e=edges[G[u][i]];if(dist[u]+1==dist[e.to] && (d=dfs(e.to,min(e.cap-e.flow,low)))>0 ){e.flow+=d;edges[G[u][i]^1].flow-=d;flow+=d;low-=d;if(low==0)break;}}return flow;}int Dinic(){int flow=0;while(bfs()){memset(cur,0,sizeof(cur));flow+=dfs(s,maxint);}return flow;}int main(){int T;int i,j;int maxn;int flag=1;int sum;cin>>T;while(T--){sum=0;int n,m;maxn=0;cin>>n>>m;edges.clear();for(i=0;i<=1000;i++)G[i].clear();for(i=1;i<=n;i++){int pi,ci,ei;cin>>pi>>ci>>ei;sum+=pi;maxn=max(maxn,ei);add(0,i,pi);for(j=ci;j<=ei;j++)add(i,n+j,1);}for(i=1;i<=maxn;i++)add(n+i,maxn+n+1,m);s=0,t=maxn+n+1;int tmp=Dinic();if(sum==tmp)    printf("Case %d: Yes\n\n",flag++);elseprintf("Case %d: No\n\n",flag++);}return 0;}