ZOJ-2676-Network Wars(01分數規劃+最小割)
阿新 • • 發佈:2019-02-14
while( ( t=DFS(S,T,INF) ) >=eps)沒加括弧wa到哭
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstring> #include <cstdio> #include <algorithm> #include <iostream> #include <queue> #include <cmath> #include <string> #include <map> #include <stack> using namespace std; #define INF 0x3f3f3f3f #define MAXN 5007 #define MAXM 5007 int n,m; const int mod=499999; #define eps 1e-9 int x[MAXN],y[MAXN],used[MAXN],vis[MAXN]; double z[MAXN]; int GAP[MAXN],dis[MAXN]; int deep[MAXN]; struct node { int v,next; double flow; } edge[MAXM]; int ind, head[MAXN]; void add_(int u, int v, double flow) { edge[ind].v=v; edge[ind].flow=flow; edge[ind].next=head[u]; head[u]=ind++; edge[ind].v=u; edge[ind].flow=0; edge[ind].next=head[v]; head[v]=ind++; } bool BFS(int S, int T) { memset(deep,0,sizeof(deep)); deep[S]=1; queue<int> q; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i+1; i=edge[i].next) { int v= edge[i].v; if(!deep[v]&&edge[i].flow>=eps) { deep[v]=deep[u]+1; q.push(v); if(v==T)return 1; } } } return 0; } double DFS(int S, int T, double max_) { if(S==T)return max_; double ans=0,f; for(int i=head[S]; i+1; i=edge[i].next) { int v=edge[i].v; if(deep[S]+1==deep[v] && edge[i].flow>eps) { f=DFS(v,T,min(max_-ans,edge[i].flow)); ans+=f; edge[i].flow-=f; edge[i^1].flow+=f; } } if(eps<=ans)return ans; deep[S]=0; return 0; } double Dinic(int S, int T) { double ans=0,t; while(BFS(S,T)) { while( ( t=DFS(S,T,INF) ) >=eps) ans+=t; } return ans; } void D(int u) { vis[u]=1; for(int i=head[u]; i+1; i=edge[i].next) { int v=edge[i].v; if(!vis[v] && edge[i].flow>=eps)D(v); } } int main() { int cp=0; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0; i<m; ++i) scanf("%d%d%lf",&x[i],&y[i],&z[i]); double l=0.0,r=0.0,ans,mid; for(int i=0; i<m; ++i)r+=z[i]; int cnt=0; while(r-l>=eps) { mid=(l+r)/2.0; ind=0; ans=0; memset(head,-1,sizeof(head)); for(int i=0; i<m; ++i) { if(z[i]<mid) ans+=z[i]-mid; else { add_(x[i],y[i],z[i]-mid); add_(y[i],x[i],z[i]-mid); } } ans+=Dinic(1,n); if(fabs(ans)<eps)break; if(ans<0)r=mid; else l=mid; } memset(used,0,sizeof(used)); for(int i=0; i<m; ++i)if(z[i]<mid)used[i]=1; memset(vis,0,sizeof(vis)); D(1); for(int i=0; i<m; ++i) if(vis[ x[i] ]!=vis[ y[i] ] || used[i]) cnt++; printf("%d\n",cnt); for(int i=0; i<m; ++i) if(vis[ x[i] ]!=vis[ y[i] ] || used[i]) { cnt--; if(cnt) printf("%d ",i+1); else printf("%d\n",i+1); } printf("\n"); } return 0; } /* 6 8 1 2 3 1 3 3 2 4 2 2 5 2 3 4 2 3 5 2 5 6 3 4 6 3 4 5 1 2 2 1 3 2 2 3 1 2 4 2 3 4 2 */