uva 11248 网络流 【扩一条边的容量至某一指定值】
来源:互联网 发布:java重载规则 编辑:程序博客网 时间:2024/06/01 07:40
【求出最大流后,给一条边扩容后,希望最大流能提升至某一指定值】的若干优化:
1.只扩最小割的边: 错误(即使最小割唯一)
2.只扩flow==cap的边:正确
#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,1const int inf=2000000010;//const long long INF=1LL<<50;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=111;int n,m,cc,yy;int b[10005][3];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){} bool operator<(const Edge &oth)const { if (from!=oth.from) return from<oth.from; return to<oth.to; } }; int n,m,s,t;//结点数,边数(含反向弧),源点,汇点 vector<Edge> edges,pp,anss;//边表,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)//重边不影响 { //printf("%d %d %d\n",from,to,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(); if (flow+yy>=cc) return flow; 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 dfs1(int x) { vis[x]=1; for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.flow<e.cap&&!vis[e.to]) dfs1(e.to); } } void dfs2(int x) { vis2[x]=1; for(int i=0;i<g[x].size();++i) if(!vis2[g[x][i]]) dfs2(g[x][i]); } vector<int> g[MAXN]; bool vis2[MAXN]; void solve() { for (int i=0;i<n;i++) g[i].clear(); for (int i=0;i<edges.size();i++) if (edges[i].flow<edges[i].cap) g[edges[i].to].push_back(edges[i].from); memset(vis,0,sizeof(vis)); memset(vis2,0,sizeof(vis2)); dfs1(s); dfs2(t); pp.clear(); anss.clear(); for (int i=0;i<edges.size();i++)pp.pb(edges[i]); for (int i=0;i<pp.size();i+=2) if (pp[i].flow==pp[i].cap) { edges.clear(); for (int ii=0;ii<pp.size();ii++)edges.pb(pp[ii]); edges[i].cap=cc; int tmp=Maxflow(s,t); if (tmp+yy>=cc) anss.pb(edges[i]); } }}it;void doit(){ it.init(n); for (int i=1;i<=m;i++) {scanf("%d%d%d",&b[i][0],&b[i][1],&b[i][2]); b[i][0]--;b[i][1]--; it.AddEdge(b[i][0],b[i][1],b[i][2]); } yy=0; yy=it.Maxflow(0,n-1); if (yy>=cc){printf("possible\n");return;} it.solve(); sort(it.anss.begin(),it.anss.end()); if (it.anss.size()==0) {printf("not possible\n");return;} printf("possible option:"); bool have=0; for (int i=0;i<it.anss.size();i++) { if (have) printf(","); printf("(%d,%d)",it.anss[i].from+1,it.anss[i].to+1); have=1; } printf("\n");}int main(){ int id=0; //freopen("in.txt","r",stdin); while (scanf("%d%d%d",&n,&m,&cc),n||m||cc) {printf("Case %d: ",++id); doit(); }}/*4 4 51 2 51 3 52 4 53 4 54 4 53 4 11 2 11 3 52 4 54 4 51 2 11 3 12 4 13 4 10 0 0*/
0 0
- uva 11248 网络流 【扩一条边的容量至某一指定值】
- uva 11248 Frequency Hopping(增加边的容量使最大流达到某个值)
- 一条sql求某一字段不同值出现的次数
- Uva 11248 求只修改一条边的流量使得最大流>c 的所有可行边
- MATLAB 图像处理 灰度图 将图像中某一行或者某一列的灰度值 绘制成一条曲线
- 取得Gridview的指定某一列的值
- 调整割边的流量使网络通过c流量 网络流 网络扩容 uva 11248
- Oracle去除重复(某一列的值重复),取最新(日期字段最新)的一条数据
- poj 3498(满足点容量限制的网络流)
- 有顶容量约束的网络最大流
- mysql数据库表中删除某一列值重复的全部行和只留一条
- mysql数据库表中删除某一列值重复的全部行和只留一条
- 查询指定的上一条或者下一条信息
- 随机读取数据库中某一表的一条记录
- 随机读取数据库中某一表的一条记录
- 一条命令杀死指定名字的进程
- dede调用指定的某一篇文章&排序
- 查询某一条记录的前一条记录和后一条记录
- 小白学jquery Mobile《构建跨平台APP:jQuery Mobile移动应用实战》连载五(给按钮加图标)
- HibernateTemplate、HibernateDaoSupport两种方法实现增删改查Good
- PHP、JSP间的比较
- hbase安装配置
- 字符对齐
- uva 11248 网络流 【扩一条边的容量至某一指定值】
- 解决kindeditor上传图片、文件的错误
- Sunday 算法的 O-C语言实现
- 存储过程与函数的区别
- hadoop 用户权限设置
- SQL-ORDER BY 多字段排序
- RMAN—非归档模式—完全恢复
- linux下如何挂载U盘,虚拟机下如何挂载U盘,Ubuntu下如何挂载U盘
- Sphinx 2.2.3 安装和配置,英文数字中文搜索