HDU 2883 kebab【最大流】(判断是否满流)
来源:互联网 发布:iphone 5s电池淘宝威锋 编辑:程序博客网 时间:2024/05/21 22:22
题意: 有一个烧烤机,每次最多能烤 m 块肉,现在有 n 个人来买烤肉,每个人到达时间为 si,离开时间为 ei,点的烤肉数量为 ci,点的烤肉所需烘烤时间为 di,
每个人要烤的肉可以分成若干份在同时烤,问是否存在一种方案可以满足所有顾客的需求。
分析: 将所有的到达时间和结束时间按升序排序,得到 x <= 2n-1 个时间区间。
建图:
s为源,t为汇,
每个顾客i作为一个结点并连边(s, i, ni*ti)
每个区间j作为一个结点并连边(j, t, (ej-sj)*M),其中sj, ej分别表示区间j的起始时间和终止时间
对任意顾客i和区间j,若 [sj, ej] 完全包含在 [si, ei] 之中,则连边(i, j, INF)
若最大流等于 ∑ni*ti 则是 Yes,否则是 No。
G[]数组不能开太大,会CE,应该是内部内存不能太大的缘故吧!
<span style="color:#333333;">#include<iostream>#include<string>#include<algorithm>#include<cstdlib>#include<cstdio>#include<set>#include<map>#include<vector>#include<cstring>#include<stack>#include<cmath>#include<queue>using namespace std;#define CL(x,v); memset(x,v,sizeof(x));#define INF 0x3f3f3f3f#define LL long long#define REP(i,r,n) for(int i=r;i<=n;i++)#define RREP(i,n,r) for(int i=n;i>=r;i--)#define MAXN 8005+200struct Edge{ int from,to,cap,flow;};bool cmp(const Edge& a,const Edge& b){ return a.from < b.from || (a.from == b.from && a.to < b.to);}struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[MAXN]; //此处内存不能开大,会莫名的 CE,可能是内部空间不能开太大的原因 bool vis[1005]; int d[1005]; int cur[1005]; void init(int n){ this->n=n; for(int i=0;i<=n;i++)G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap){ edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0});//当是无向图时,反向边容量也是cap,有向边时,反向边容量是0 m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ CL(vis,0); queue<int> Q; Q.push(s); d[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; d[e.to]=d[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(d[x]+1==d[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; } //当所求流量大于need时就退出,降低时间 int Maxflow(int s,int t,int need){ this->s=s;this->t=t; int flow=0; while(BFS()){ CL(cur,0); flow+=DFS(s,INF); if(flow>need)return flow; } return flow; } //最小割割边 vector<int> Mincut(){ BFS(); vector<int> ans; for(int i=0;i<edges.size();i++){ Edge& e=edges[i]; if(vis[e.from]&&!vis[e.to]&&e.cap>0)ans.push_back(i); } return ans; } void Reduce(){ for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; } void ClearFlow(){ for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; }};Dinic solver;int col[1005];struct Node{ int ei,ej;}tt[1005],ren[1005];int main(){ int n,m; int cas=0,T; //scanf("%d",&T); while(~scanf("%d%d",&n,&m)) { int s=0,t=1001; int c=0,tot=0; int N=MAXN; // 301~300+tot是“time”的点,1~n 表示第i个人, // s为超级源点,t为超级汇点 solver.init(N); int sum=0; for(int i=1;i<=n;i++) { int si,ni,ei,ti; scanf("%d%d%d%d",&si,&ni,&ei,&ti); sum+=ni*ti; ren[i].ei=si; ren[i].ej=ei; solver.AddEdge(s,i,ni*ti); //for(int j=si+1;j<=ei;j++) // solver.AddEdge(i+1000000,j,ni); col[c++]=si; col[c++]=ei; } sort(col,col+c); int now=col[0]; for(int i=1;i<c;i++) if(col[i]!=now){ tt[tot].ei=now; tt[tot++].ej=col[i]; now=col[i]; } for(int i=0;i<tot;i++) { solver.AddEdge(300+i,t,(tt[i].ej-tt[i].ei)*m); for(int j=1;j<=n;j++) if( tt[i].ei >=ren[j].ei && tt[i].ej<=ren[j].ej ) solver.AddEdge(j,300+i,INF) //,printf("%d: %d -> %d\n",i,j,300+i) ; } int ans=solver.Maxflow(s,t,INF); // printf("Case %d: ",++cas); // printf("ans=%d\n",ans); if(ans==sum) puts("Yes"); else puts("No"); } return 0;}</span>
0 0
- HDU 2883 kebab【最大流】(判断是否满流)
- hdu 2883 kebab(最大流)
- hdu 2883 kebab(最大流,判断满流,区间化点)
- HDU 2883 kebab(离散化+最大流)
- hdu 2883 kebab 【网络最大流】
- HDU 2883 kebab(最大流)
- HDU - 2883 kebab (最大流)
- HDU 2883 kebab 最大流(纯靠建图)
- HDU 2883 kebab(最大流,满流)
- HDU 2883 kebab(离散化+最大流)
- HDU 2883 kebab(离散化+最大流)
- HDU 2883 kebab 最大流建模
- hdu 2883 kebab (最大流 + 建图)
- hdu 3572 Task Schedule hdu 2883 kebab 最大流
- HDU 2883kebab(网络流之最大流)
- hdu 2883 kebab(存个最大流模板)
- 【HDU】 2883 kebab(最大流+时间段离散化)
- hdu 2883 kebab(最大流dinic邻接表)
- android动画
- C语言点滴之——变量定义_01
- QComboBox 编辑组合框
- 21天理论介绍
- QComboBox 编辑组合框
- HDU 2883 kebab【最大流】(判断是否满流)
- QSplitter 学习
- C++ Primer 笔记
- 23种设计模式笔记
- 分隔控件(Splitters)
- phonegap 屏蔽页面Bounce回弹
- 英文段落排版
- 滚动区域(Scrolling Areas)
- maven在eclipse中的实践