uva 11167 网络流 【好题】
来源:互联网 发布:哈鲁留学怎么样 知乎 编辑:程序博客网 时间:2024/05/29 12:39
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cstdlib>#include <cmath>#include <queue>#include <vector>#include <map>#define pb push_back#define mp make_pair#define eps 1e-9#define zero(x) (fabs(x)<eps)#define pi acos(-1.0)#define f1 first#define f2 second#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define initial 1,n,1#define CLR(x,y) memset(x,y,sizeof(x))using namespace std;typedef long long LL;typedef pair <int, int> PII;template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}const int MAXN=330,inf=0x3f3f3f3f;vector<pair<int,int> > anss[105];int vv[50005][5];int a[105][3];int tt[210];int n,mm;struct ISAP{ struct Edge { int from,to,cap,flow; Edge(){} Edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d){} }; int n,m,s,t;//结点数,边数(含反向弧),源点,汇点 vector<Edge> edges;//边表,edges[e]&edges[e^1]互为反向弧 vector<int> G[MAXN];//邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[MAXN];//BFS使用 int d[MAXN];//从起点到i的距离 int cur[MAXN];//当前弧下标 int p[MAXN];//可增广路上的上一条弧 int num[MAXN];//距离标号计数 void AddEdge(int from,int to,int cap)//重边不影响 { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0));//容量为0,表示反向弧 m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } void init(int n) { this->n=n; for(int i=0;i<n;++i) G[i].clear(); edges.clear(); } void BFS()//反向 { for (int i=0;i<n;i++) d[i]=n+10; //!!! memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(t); d[t]=0; vis[t]=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]^1]; if(!vis[e.from]&&e.cap>e.flow) { vis[e.from]=1; d[e.from]=d[x]+1; Q.push(e.from); } } } } int Augment() { int x=t,a=inf; while(x!=s) { Edge& e=edges[p[x]]; a=min(a,e.cap-e.flow); x=edges[p[x]].from; } x=t; while(x!=s) { edges[p[x]].flow+=a; edges[p[x]^1].flow-=a; x=edges[p[x]].from; } return a; } int Maxflow(int s,int t)//结点数 { this->s=s,this->t=t; int flow=0; BFS(); memset(num,0,sizeof(num)); for(int i=0;i<n;++i) if (d[i]!=n+10)++num[d[i]];//!!! int x=s; memset(cur,0,sizeof(cur)); while(d[s]<n) { if(x==t) { flow+=Augment(); x=s; } int ok=0; for(int i=cur[x];i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.cap>e.flow&&d[x]==d[e.to]+1)//Advance { ok=1; p[e.to]=G[x][i]; cur[x]=i; x=e.to; break; } } if(!ok)//Retreat { int m=n-1; for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.cap>e.flow) m=min(m,d[e.to]); } if(--num[d[x]]==0) break;//gap优化 num[d[x]=m+1]++; cur[x]=0; if(x!=s) x=edges[p[x]].from; } } return flow; } void solve(int nn) { memset(vv,0,sizeof(vv)); int tr=-1,tl=-1,last=-1; for (int i=0;i<edges.size();i++) if (edges[i].from<=nn&&edges[i].from>=1&&edges[i].flow>0) { int index=edges[i].to-nn-1,res=edges[i].flow; for(int k=0;k<mm;k++) { if(vv[index][k]==tt[index+1]-tt[index])continue; if(vv[index][k]+res<=tt[index+1]-tt[index]) { anss[edges[i].from].pb(mp(tt[index]+vv[index][k],tt[index]+vv[index][k]+res)); vv[index][k]+=res; break; } else { res-=(tt[index+1]-tt[index]-vv[index][k]); anss[edges[i].from].pb(mp(tt[index]+vv[index][k],tt[index+1])); vv[index][k]=tt[index+1]-tt[index]; if(!res)break; } } } }}it;void doit(){ scanf("%d",&mm); int id=-1,sum=0; for (int i=1;i<=n;i++) {scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); tt[++id]=a[i][1]; tt[++id]=a[i][2]; sum+=a[i][0]; } sort(tt,tt+id+1); int cnt=unique(tt,tt+id+1)-tt; it.init(n+cnt+1); int s=0,t=n+cnt; for (int i=1;i<=n;i++) for (int j=1;j<cnt;j++) if (a[i][1]<=tt[j-1]&&a[i][2]>=tt[j]) it.AddEdge(i,n+j,tt[j]-tt[j-1]); for (int i=1;i<=n;i++) it.AddEdge(0,i,a[i][0]); for (int i=1;i<cnt;i++) it.AddEdge(n+i,t,(tt[i]-tt[i-1])*mm); int ans=it.Maxflow(s,t); for (int i=1;i<=n;i++)anss[i].clear(); if (ans!=sum) { printf("No\n"); return; } printf("Yes\n"); it.solve(n); for (int i=1;i<=n;i++) { sort(anss[i].begin(),anss[i].end()); for(int j=1;j<anss[i].size();j++) if(anss[i][j].f1==anss[i][j-1].f2) { anss[i][j-1].f2=anss[i][j].f2; anss[i].erase(anss[i].begin()+j); j--; } printf("%d",anss[i].size()); for (int j=0;j<anss[i].size();j++) printf(" (%d,%d)",anss[i][j].f1,anss[i][j].f2); printf("\n"); }}int main(){ //freopen("in.txt","r",stdin); int id=0; while (scanf("%d",&n),n) {printf("Case %d: ",++id); doit(); }}/*3 22 1 42 1 42 1 4*/
0 0
- uva 11167 网络流 【好题】
- uva 10125 - Sumsets好题
- UVa 11235 RMQ好题
- UVa 11732 trie好题
- LA 2957 网络流【好题】
- 网络流(好)hdu4183
- Uva 563 网络流
- uva 10779 Collectors Problem(最大流,好题)
- UVa 11572 - Unique Snowflakes (好题)
- UVa 129 Krypton Factor (回溯好题)
- UVa 1346 Songs (贪心好题)
- Uva 11374 最短路 好题
- uva 12655 (树链剖分+生成树 好题)
- uva 11082(网络流)
- 网络流 UVA 12264 Risk
- UVA 10480 Sabotage 网络流
- Monkeys in the Emei Mountain -- UVA - 11167 (网络流)
- poj1149-------网络流的题目,关键是构图,好题!!!
- Visible Lattice Points poj+欧拉函数的应用+水水的过了
- 中国剩余定理
- Dividing coins - UVa 562 dp背包
- poj2528Mayor's posters(线段树)
- 对libevent+多线程服务器模型的C++封装类
- uva 11167 网络流 【好题】
- 从某道C面试题开始……
- PorterDuff.Mode
- 判断输入的任意整数m是否为素数。
- Graph Automata Player
- java 内省机制
- Maven仓库汇总
- 网页静态化技术
- ARM学习随笔(12)定时器查询方式和中断方式