bzoj1001

题解:

网络流求最小割

平面图转对偶图裸题

注意细节就可以了,n or m=1特判

代码:

#include <bits/stdc++.h> 
using namespace std; 
queue <int> q; 
int n,m,l,s,t,x,y; 
#define maxn 6000000
int dis[maxn],head[maxn]; 
bool inq[maxn]; 
int p[2000][2000]; 
#define INF 1e9  
struct re{ 
    int a,b,c; 
}a[maxn]; 
void arr(int x,int y,int z) 
{ 
    a[++l].a=head[x]; 
    a[l].b=y; 
    a[l].c=z; 
    head[x]=l; 
} 
/*void arr(int x,int y,int z) 
{ 
  if (f[x][y]==0) f[x][y]=z; else f[x][y]=min(f[x][y],z); 
}*/
int main(){     cin>>n>>m; 
    if (n == 1 || m == 1)   
    {   
        if (n > m) swap(n, m);   
        int ans = INF;   
        for (int i = 1; i < m; ++i)   
        {   
            int x;   
            cin>>x;   
            if (x < ans) ans = x;   
        }   
        cout<<ans;   
        exit(0);   
    }   
    s=0; t=(n-1)*(m-1)*2+1; 
    for (int i=1;i<=m-1;i++) 
    { 
        cin>>x; arr(0,i,x);arr(i,0,x); 
    } 
    for (int j=2;j<=n-1;j++) 
      for (int i=1;i<=m-1;i++) 
      { 
        cin>>y; 
        int x=(j-1)*(m-1)*2; 
        arr(x+i,x+i-(m-1),y); arr(x+i-(m-1),x+i,y); 
      } 
    for (int i=1;i<=m-1;i++) 
    { 
        cin>>y; 
        arr(t-m+i,t,y); arr(t,t-m+i,y); 
    } 
    for (int i=1;i<=n-1;i++) 
      for (int j=1;j<=m;j++) 
        cin>>p[i][j]; 
    x=m; 
    for (int i=1;i<=n-1;i++) 
    { 
      y=p[i][1]; 
        arr(x,t,y); arr(t,x,y); 
        x+=2*(m-1); 
    } 
    for (int j=2;j<=m-1;j++) 
    { 
        x=m+j-1; 
        for (int i=1;i<=n-1;i++) 
        { 
              y=p[i][j]; 
            arr(x,x-m,y); arr(x-m,x,y); 
            x+=2*(m-1);  
        } 
    } 
    x=m-1; 
    for (int i=1;i<=n-1;i++) 
    { 
      y=p[i][m]; 
        arr(x,s,y); arr(s,x,y); 
        x+=2*(m-1); 
    } 
    for (int i=1;i<=n-1;i++) 
    { 
        int x=(m-1)*2*(i-1)+1; 
        for (int j=1;j<=m-1;j++) 
        { 
            cin>>y; 
            arr(x,x+(m-1),y); arr(x+(m-1),x,y); 
            x++; 
        } 
  } 
 /*     for (int i=0;i<=t-1;i++) 
    { 
      for (int j=0;j<=t;j++) 
        cout<<i<<" "<<j<<" "<<f[i][j]<<endl; 
      cout<<endl; 
  }*/
    for (int i=1;i<=t;i++) dis[i]=INF; 
    q.push(0); 
    while (!q.empty()) 
    { 
        int x=q.front(); q.pop(); 
        int u=head[x]; 
        while (u) 
        { 
            int v=a[u].b; 
            if (dis[x]+a[u].c<dis[v]) 
            { 
              dis[v]=dis[x]+a[u].c; 
              if (!inq[v]) 
              { 
                 q.push(v); inq[v]=1; 
              } 
            } 
            u=a[u].a; 
        } 
        inq[x]=0; 
    } 
    cout<<dis[t]; 
} 

 

posted @ 2018-02-12 15:37  尹吴潇  阅读(119)  评论(0编辑  收藏  举报