hdu2883
2014-02-28 11:54
369 查看
再来一题最大流。
这里的建模,与汇点连接的是时间区间。可以理解成在一段时间里总共可以制作多少个kebab。如何这段时间满足客人的要求,则可以将该区间与客人相连,弧的流量设为能够制作的上界,或者直接设为INF就行。其余的建模步骤和常规任务分配最大流建模方式类似。
这里的建模,与汇点连接的是时间区间。可以理解成在一段时间里总共可以制作多少个kebab。如何这段时间满足客人的要求,则可以将该区间与客人相连,弧的流量设为能够制作的上界,或者直接设为INF就行。其余的建模步骤和常规任务分配最大流建模方式类似。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> #define INF 0x7fffffff #define maxn 25000 using namespace std; int n,m; struct Edge{ int from,to,cap,flow; }; class Dinic{ public: int s,t,c; vector<Edge>edges; vector<int>G[maxn]; bool vis[maxn]; int dist[maxn]; int cur[maxn]; public: void AddEdge(int from,int to,int cap){ edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0}); c=edges.size(); G[from].push_back(c-2); G[to].push_back(c-1); } bool BFS(){ queue<int>Q; memset(vis,0,sizeof(vis)); Q.push(s); dist[s]=0; vis[s]=1; while(!Q.empty()){ int x=Q.front();Q.pop(); for(int i=0;i<G[x].size();i++){ Edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ vis[e.to]=1; dist[e.to]=dist[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x==t||a==0)return a; int flow=0,f; for(int& i=cur[x];i<G[x].size();i++){ Edge& e=edges[G[x][i]]; if(dist[x]+1==dist[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int Maxflow(int s,int t){ this->s=s;this->t=t; int flow=0; while(BFS()){ memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); flow+=DFS(s,INF); } return flow; } void init(){ edges.clear(); for(int i=0;i<maxn;i++){ G[i].clear(); dist[i]=0; } } }Do; struct Time{ int s,e; }; Time *timei; int *timej; int Judge(int i,int j){ if(timei[i].s>timej[j]) return 1;//不满足上界 if(timei[i].e<timej[j+1]) return 2;//不满足下界 return 3;//满足 } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ Do.init(); timei=new Time[n+1]; timej=new int[2*n+1];int pj=1,Sum=0; for(int i=1;i<=n;i++){ int si,ni,ei,ti; scanf("%d%d%d%d",&si,&ni,&ei,&ti); Do.AddEdge(0,i,ni*ti); Sum+=(ni*ti); timei[i]=(Time){si,ei}; timej[pj++]=si; timej[pj++]=ei; } sort(timej+1,timej+1+2*n); for(int i=1;i<=n;i++){ for(int j=1;j<=n*2-1;j++){ if(Judge(i,j)==2)break; if(Judge(i,j)==3) Do.AddEdge(i,n+j,INF); } } for(int j=1;j<=2*n-1;j++){ Do.AddEdge(n+j,3*n,(timej[j+1]-timej[j])*m); } if(Do.Maxflow(0,3*n)==Sum)printf("Yes\n"); else printf("No\n"); delete timei; delete timej; } return 0; }
相关文章推荐
- lte 切换
- 程序员级别鉴定书(.NET面试问答集锦)
- UILabel 的键盘操作
- [ASP.NET 技术点滴] Jquery 前端验证
- ThreadPoolExecutor一些原理问题
- 程序员级别鉴定书(.NET面试问答集锦) 推荐
- 点与多边形的叠加分析
- Copy List with Random Pointer (deep copy)
- 本示例演示在Android中实现图片左右滑动效果。
- vs2010调试断点无法命中问题
- Linux下通过编译源码安装软件的流程
- 进程 & 线程
- 二维数组作为函数的参数传递
- Winform合并多个Excel文件到一个文件中(源文件.xls,实际是.xml)
- 解决其他系统和discuz同步登录和退出的问题!
- solr3.6到solr4.1升级,schema版本号区别等
- ASCII码表
- Android资源文件 - 使用资源存储字符串 颜色 尺寸 整型 布尔值 数组
- linux C 获取当前目录的实现(转-Blossom)
- PHP5.4新特性