这道题尼玛的让我蛋疼无比。。第一次遇到,直接最大流,看了半天把题目理解错了。。然后才知道,是求最小割集的最少边数,

没思路。然后看网上的解法。。知道大神怎么解的之后自己写,(http://hi.baidu.com/mengyun1993/blog/item/c30d193c9a85932870cf6cda.html),,

我自己写的时候就是没办法AC。。写了个DINIC,超时,,然后写ISAP,,WA,搞了半天都没过。。万念俱灰,写个EK。。直接结果都出不来。。

实在蛋疼。。搞不下去了。。下面贴我各种错的代码,望哪位大神批判。。

 

#include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;
const int N=210;
const int INF = 0x7FFFFFFF;
int n,m,map[N][N],path[N],flow[N],start,end;
queue<int> q;

 

int bfs()
{
 int i,t;
 while(!q.empty())
  q.pop();
 memset(path,-1,sizeof(path));
 path[start]=0,flow[start]=INF;
 q.push(start);
 while(!q.empty())
 {
  t=q.front();
  q.pop();
  if(t==end) break;
  for(i=1;i<=m;i++)
  {

 

   if(i!=start && path[i]==-1 && map[t][i])
   {
    flow[i]=flow[t]<map[t][i]?flow[t]:map[t][i];
    q.push(i);
    path[i]=t;
   }
  }
 }
 if(path[end]==-1) return -1;
    return flow[m];                   //一次遍历之后的流量增量
}
int Edmonds_Karp()
{
 int max_flow=0,step,now,pre;
 while((step=bfs())!=-1)
 {          //找不到增路径时退出
  max_flow+=step;
  now=end;
  while(now!=start)
  {
   pre=path[now];
   map[pre][now]-=step;      //更新正向边的实际容量
   map[now][pre]+=step;      //添加反向边
   now=pre;
  }
 }
 return max_flow;
}
int main()
{
 int cas;
 int i,u,v,cost,d;
 int Case=0;
 while(scanf("%d",&cas)!=EOF)
 {
  while(cas--)
  {
   scanf("%d %d",&n,&m);
   memset(map,0,sizeof(map));
   for(i=0;i<m;i++)
   {
    scanf("%d %d %d %d",&u,&v,&cost,&d);
    map[u][v]=cost*100001+1;           //not just only one input
    if(d==1)
     map[v][u]=cost*100001+1;
   }
   start=0,end=n-1;
   __int64 ans=Edmonds_Karp();
   printf("Case %d: %I64d\n",++Case,ans%100001);
  }
 }
 return 0;
}
/*
#include<cstdio> 
#include <iostream>
#include<cstring> 
#include<queue> 
#include<algorithm> 
#define N 20001
#define inf 99999999 
using namespace std; 

 

  int s,t,dis[N],pre[N],gap[N],flow[N][N]; 
  struct edge 
  { 
  int v,w; 
  edge *next,*rev; 
  edge(){next=0;} 
  edge(int vv,int ww,edge *e){v=vv;w=ww;next=e;} 
  }*adj[N],*path[N],*e; 
  int min(int x,int y)
  {
  if(x>y)
  return y;
  else
  return x;
  }
  void insert(int u,int v,int w) 
  { 
  edge *p=new edge(v,w,adj[u]); 
  adj[u]=p; 
  edge *q=new edge(u,0,adj[v]); 
  adj[v]=q; 
  p->rev=q; 
  q->rev=p; 
  } 
  void bfs() 
  { 
  memset(dis,0x7f,sizeof(dis)); 
  memset(gap,0,sizeof(gap)); 
  queue<int> q; 
  dis[t]=0; 
  gap[0]=1; 
  q.push(t); 
  while(q.size()) 
  { 
        int x=q.front(); 
        q.pop(); 
        for(e=adj[x];e;e=e->next) 
        { 
  if(e->rev->w==0||dis[e->v]<t) 
  continue; 
  dis[e->v]=dis[x]+1; 
  ++gap[dis[e->v]]; 
  q.push(e->v); 
        } 
  } 
  } 
  int ISAP() 
  { 
  memset(dis,0,sizeof(dis)); 
  memset(gap,0,sizeof(gap)); 
  //bfs(); 
  int ans=0,u=s,d; 
  while(dis[s]<=t) 
  { 
        if(u==t) 
        { 
  int minflow=-1u>>1; 
  for(e=path[u];u!=s;e=path[u=pre[u]]) 
  minflow=min(minflow,e->w); 
  for(e=path[u=t];u!=s;e=path[u=pre[u]]) 
  { 
  e->w-=minflow; 
  e->rev->w+=minflow; 
  flow[pre[u]][u]+=minflow; 
  flow[u][pre[u]]-=minflow; 
  } 
  ans+=minflow; 
        }        
        for(e=adj[u];e;e=e->next) 
  if(e->w>0&&dis[u]==dis[e->v]+1) 
  break; 
        if(e) 
        { 
  pre[e->v]=u; 
  path[e->v]=e; 
  u=e->v; 
        } 
        else 
        { 
  if(--gap[dis[u]]==0) 
  break; 
  for(d=t,e=adj[u];e;e=e->next) 
  if(e->w>0) 
  d=min(d,dis[e->v]); 
  dis[u]=d+1; 
  ++gap[dis[u]]; 
  if(u!=s) 
  u=pre[u]; 
        } 
  } 
  return ans; 
  } 
  int main()
  { 
  int nn,mm;
  int cas;
  int U,V,W,d;
  int Case;
  while(scanf("%d",&cas)!=EOF)
  {
  Case=0;
  while(cas--)
  {
  scanf("%d%d",&nn,&mm);
  memset(adj,0,sizeof(adj));
  while(mm--)
  {
  scanf("%d%d%d%d",&U,&V,&W,&d);
  insert(U,V,W*100001+1);
  if(d==1)
  insert(V,U,W*100001+1);
  }
  s=0;
  t=nn-1; 
  __int64 ans=ISAP();
  printf("Case %d: %I64d\n",++Case,ans%100001);
  }
  } 
  return 0;
  }
  /*
  #include<cstdio> 
  #include<cstring> 
  #include <iostream>
  #include<algorithm> 
  #define N 5005 
  #define M 10005  //这个要够大。。
  #define inf 999999999 
  using namespace std; 
  
    int n,m,s,t,num,adj[N],dis[N],q[N]; 
    struct edge 
    { 
    int v,w,pre; 
    }e[M]; 
    int min(int x,int y)
    {
    if(x>y)
    return y;
    else
    return x;
    }
    void insert(int u,int v,int w)  //上面的insert可以写成下面这种。。
    { 
    e[num].v=v;
    e[num].w=w;
    e[num].pre=adj[u];
    adj[u]=num++;
    e[num].v=u;
    e[num].w=0;
    e[num].pre=adj[v];
    adj[v]=num++;
   
   } 
   int bfs() 
   { 
   int i,x,v,tail=0,head=0; 
   memset(dis,0,sizeof(dis)); 
   dis[s]=1; 
   q[tail++]=s; 
   while(head<tail) 
   { 
   x=q[head++];         
   for(i=adj[x];i!=-1;i=e[i].pre) 
            if(e[i].w&&dis[v=e[i].v]==0) 
            { 
   dis[v]=dis[x]+1; 
   if(v==t) 
   return 1; 
   q[tail++]=v; 
            } 
   } 
   return 0; 
   } 
   int dfs(int s,int limit) 
   { 
   if(s==t) 
   return limit; 
   int i,v,tmp,cost=0; 
   for(i=adj[s];i!=-1;i=e[i].pre) 
   if(e[i].w&&dis[s]==dis[v=e[i].v]-1) 
   { 
            tmp=dfs(v,min(limit-cost,e[i].w)); 
            if(tmp>0) 
            { 
   e[i].w-=tmp; 
   e[i^1].w+=tmp; 
   cost+=tmp; 
   if(limit==cost) 
   break; 
            } 
            else dis[v]=-1; 
   } 
   return cost; 
   } 
   int Dinic() 
   { 
   int ans=0; 
   while(bfs()) 
   ans+=dfs(s,inf); 
   return ans; 
   } 
   int main()
   { 
   int nn,mm;
   int cas;
   int u,v,d;
   int Case;
   __int64 w;
   while(scanf("%d",&cas)!=EOF)
   {
   Case=0;
   for(int i=0;i<cas;i++)
   {
   scanf("%d%d",&nn,&mm);
   num=0;
   memset(adj,-1,sizeof(adj));
   for(int j=0;j<mm;j++)
   {
   scanf("%d%d%I64d%d",&u,&v,&w,&d);
   u++;v++;
   insert(u,v,w*1000001+1);
   if(d==1)
   insert(v,u,w*1000001+1);
   }
   s=1;
   t=nn; 
   __int64 ans=Dinic();
   printf("Case %d: %I64d\n",Case++,ans%1000001);
   }
   } 
   return 0;
}*/

 

posted on 2012-01-31 23:32  →木头←  阅读(341)  评论(0编辑  收藏  举报