LA 4597 网络流【有上下界】
来源:互联网 发布:魔侠传 网络导常检测 编辑:程序博客网 时间:2024/05/16 12:31
#include<cstring>#include<cstdio>#include<algorithm>#include<queue>#define pb push_back#define mp make_pair#define f1 first#define f2 secondusing namespace std;const int MAXN=110, inf=0x3f3f3f3f;struct ISAP{ struct Edge { int from,to,cap,flow,low,real; Edge(){} Edge(int a,int b,int c,int d,int e,int f):from(a),to(b),cap(c),flow(d),low(e),real(f){} }; int n,m,s,t,ss,tt,lowtot;//结点数,边数(含反向弧),源点,汇点 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,int low)//重边不影响 { //printf("%d %d %d\n",from,to,cap); edges.push_back(Edge(from,to,cap,0,low,1)); edges.push_back(Edge(to,from,0,0,low,0));//容量为0,表示反向弧 m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } void add(int from,int to,int low,int ma) { lowtot+=low; if (low==0) {AddEdge(from,to,ma,0);return;} AddEdge(ss,to,low,0); AddEdge(from,to,ma-low,low); AddEdge(from,tt,low,0); } void init(int n) { this->n=n;ss=n-2;tt=n-1; for(int i=0;i<n;++i) G[i].clear(); edges.clear();lowtot=0; } void BFS()//反向 { 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; for (int i=0;i<n;i++) d[i]=0; //!!! memset(num,0,sizeof(num)); for(int i=0;i<n;++i) ++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; } vector<int> anss; void dfs(int x) { anss.pb(x); for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if (e.real&&e.low) if (edges[G[x][i]-2].flow&&edges[G[x][i]+2].flow) { edges[G[x][i]-2].flow--; edges[G[x][i]+2].flow--; dfs(e.to); break; } } } void solve(int left) { int size=edges.size(); int id=0; for (int i=0;i<size;i++) if (edges[i].real&&edges[i].low&&edges[i].flow) {edges[i-2].flow+= edges[i].flow; edges[i+2].flow+= edges[i].flow; } for (int i=0;i<size;i++) if (edges[i].from==0&&edges[i].real) for (int j=0;j<edges[i].flow;j++) { anss.clear();left--; dfs(edges[i].to); int anssize=anss.size(); for (int ii=0;ii<anssize;ii++) printf("%d%c",anss[ii],(ii==anssize-1)?'\n':' '); } }}it;vector<pair<int,int > > aa;int n,pp;int ok(int mid,int ff=0){ int s=0,t=n+1; it.init(t+3); for (int i=1;i<=n;i++) {it.AddEdge(s,i,inf,0); it.AddEdge(i,t,inf,0); } it.AddEdge(t,s,mid,0); for (int i=0;i<pp;i++) it.add(aa[i].f1,aa[i].f2,1,inf); int ans=it.Maxflow(t+1,t+2); if (!ff)return ans>=it.lowtot; else return ans;}void doit(){ aa.clear(); for (int i=1,x,y;i<=n;i++) {scanf("%d",&x); while (x--) { scanf("%d",&y); aa.pb(mp(i,y)); } } pp=aa.size(); int l=1,r=pp,mid,day; //r一开始为n,被自己2跪了 while (r>=l) { mid=(l+r)>>1; if (ok(mid,0)) {day=mid; r=mid-1;} else l=mid+1; } printf("%d\n",day); int ans=ok(day,1); // printf("flow=%d\n",ans); it.solve(day);}int main(){ while(scanf("%d",&n)!=EOF)doit(); return 0;}/*61 31 31 42 5 6 00*/
0 0
- LA 4597 网络流【有上下界】
- 有上下界的网络流
- 【有上下界的网络流】
- 有上下界限制的网络流
- 有上下界的网络流专辑
- 有上下界的网络流问题
- 有上下界网络流问题
- 有上下界的网络流
- 有上下界网络流问题
- 有上下界网络流问题
- 有上下界的网络流
- 有上下界的网络流问题
- 有上下界的网络流
- 有上下界的网络流
- 【有上下界的网络流】
- 【自用】有上下界的网络流
- 有上下界的网络流问题
- 有上下界的网络流
- Libsvm使用说明
- POJ 1274 The Perfect Stall 二分图最大匹配
- 命令模式在MVC框架中的应用
- 让您的手机、平板电脑实现移动办公
- Android 下拉刷新框架实现
- LA 4597 网络流【有上下界】
- QT之Q_OBJECT
- 连续多次进入使用了MJRefresh的页面应用会崩 An instance 0xdb48a00 of class UITableView was deallocated while key value
- except切忌和pass搭配使用
- .NET多线程
- Java里清空缓冲区的方法
- UVA 490 Rotating Sentences
- CentOS常用文件操作命令[百度博客搬家]
- 关于make menuconfig