ZOJ 2676 分数规划
2015-05-14 10:59
197 查看
zoj 2676 过了 sap的问题,准备找个好点的sap板子 #include<iostream> #include<cstring> #include<string> #include<cstdio> #include<cstdlib> #include<algorithm> #define eps 1e-5 #define maxn 500 using namespace std; const int inf = 0x3f3f3f3f; const int MAXN = 110; const double esp = 1e-8; int sign(double x){ return x<-esp?-1:(x>esp);} int n, m, Max; int S, N, T; bool inde[maxn]; struct node { int u,v,cost; }in[maxn]; struct Edge{ int u, v, nxt; double f; }edge[50101]; struct Edge_Info{ int a,b,c; void input(){ scanf("%d%d%d",&a,&b,&c); } }edge_info[550]; bool vis[MAXN]; int h[MAXN], vh[MAXN]; int head[MAXN], idx; void AddEdge(int a,int b,double f){ edge[idx].u = a, edge[idx].v = b, edge[idx].f = f; edge[idx].nxt = head[a], head[a] = idx++; edge[idx].u = b, edge[idx].v = a, edge[idx].f = 0; edge[idx].nxt = head[b], head[b] = idx++; } double dfs(int u,double flow){ if(u == T) return flow; int tmp = h[u]+1; double sum = flow; for(int i = head[u]; ~i; i = edge[i].nxt){ if( sign(edge[i].f) > 0 && (h[ edge[i].v ]+1 == h[u])){ double p = dfs( edge[i].v, min(sum,edge[i].f)); edge[i].f -= p, edge[i^1].f += p, sum -= p; if( sign(sum)==0 || h[S]==N ) return flow-sum; } } for(int i = head[u]; ~i; i = edge[i].nxt ){ if( sign(edge[i].f) > 0 ) tmp = min(tmp,h[ edge[i].v ] ); } if( --vh[ h[u] ] == 0 ) h[S] = N; else ++vh[ h[u]=tmp+1 ]; return flow-sum; } double sap(){ double maxflow = 0; memset(h,0,sizeof(h)); memset(vh,0,sizeof(vh)); vh[0] = N; while( h[S] < N ) maxflow += dfs( S,inf ); return maxflow; } void DFS(int u){ vis[u] = true; for(int i = head[u]; ~i; i = edge[i].nxt){ if( sign(edge[i].f) > 0 && !vis[ edge[i].v ] ) DFS( edge[i].v ); } } void dfs(int u) { vis[u] = 1; for(int i = head[u];i != -1;i = edge[i].nxt) { if( sign(edge[i].f) > 0 && !vis[ edge[i].v ] ) dfs( edge[i].v ); } } double build(double g) { memset( head, -1, sizeof(head)); idx = 0; double all=0; for(int i=1;i<=m;i++) { double temp=in[i].cost*1.0-g; if( sign(temp) <0 ) all+=temp; else AddEdge(in[i].u,in[i].v,temp),AddEdge(in[i].v,in[i].u,temp); } return all; } bool judge(double mid) { double temp=build(mid); double res=sap(); res+=temp; if(res<eps) return true; else return false; } void output(double ans) { int a[maxn]; memset(inde,false,sizeof(inde)); memset( head, -1, sizeof(head)); idx = 0; for(int i=1;i<=m;i++) { double temp=in[i].cost*1.0-ans; if( sign(temp) <0 ) inde[i]=true; else AddEdge(in[i].u,in[i].v,temp),AddEdge(in[i].v,in[i].u,temp); } memset(vis,0,sizeof(vis)); sap(); dfs(1); int counter=0; for(int i=1;i<=m;i++) { int tempa=in[i].u; int tempb=in[i].v; if((vis[tempa]&&!vis[tempb])||(!vis[tempa]&&vis[tempb])) inde[i]=true; } for(int i=1;i<=m;i++) if(inde[i]) a[++counter]=i; printf("%d\n",counter); for(int i=1;i<counter;i++) printf("%d ",a[i]); printf("%d\n\n",a[counter]); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { S=1;T=n;N=n; int ma=0; for(int i=1;i<=m;i++) { scanf("%d%d%d",&in[i].u,&in[i].v,&in[i].cost); if(in[i].cost>ma) ma=in[i].cost; } double left=0; double right=ma*1.0; while(right-left>eps) { double mid=(left+right)*0.5; if(judge(mid)) right=mid; else left=mid; } output(left); } }
相关文章推荐
- zoj 2676 Network Wars(01分数规划+最大流)
- ZOJ 2676 Network Wars(01分数规划-二分+最小割)
- ZOJ 2676 01分数规划 最小割
- zoj 2676 Network Wars(01分数规划+网络流)
- zoj 2676(0-1)分数规划
- zoj 2676 Network Wars(最小割,01分数规划)
- zoj 2676 Network Wars 最小割+0-1分数规划
- ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)
- ZOJ-2676-Network Wars(01分数规划+最小割)
- zoj 2676 Network Wars 0-1分数规划+最小割
- ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)
- ZOJ 2676 Network Wars[01分数规划]
- 【01分数规划】 ZOJ 2676 Network Wars
- 【ZOJ】2676 Network Wars 01分数规划+最小割
- ZOJ 2676 Network Wars 最小割 分数规划
- zoj 2676 Network Wars(01分数规划+最小割)
- zoj 2676 Network Wars 【0-1分数规划 + 最小割】 【吃一堑长一智】
- 【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
- zoj 2676 网络流+01分数规划
- HDU 2676 Network Wars 01分数规划,最小割 难度:4