HDU 3807

来源:互联网 发布:淘宝运营模式图 编辑:程序博客网 时间:2024/06/05 07:02

【题目分析】
最大流最小割转最短路。


【代码】

#include <cstdio>#include <queue>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int a[401][401],tmp[401][401];int s,t,en,cnt;int h[1000001],dis[1000001],inq[1000001],ne[1000001],to[1000001],w[1000001];inline void add(int a,int b,int c){//cout<<a<<" "<<b<<" "<<c<<endl;ne[en]=h[a];to[en]=b;w[en]=c;h[a]=en++;}inline void SPFA(){    memset(dis,0x3f,sizeof dis);    queue<int>q;    q.push(s);    dis[s]=0;inq[s]=1;    while (!q.empty())    {        int x=q.front();q.pop();inq[x]=0;        for (int i=h[x];i>=0;i=ne[i])        {            if (dis[to[i]]>dis[x]+w[i])            {                dis[to[i]]=dis[x]+w[i];                if (!inq[to[i]])                {                    inq[to[i]]=1;                    q.push(to[i]);                }            }        }    }    cout<<dis[t]<<endl;}int main (){    int tt;    scanf("%d",&tt);    while (tt--)    {        memset(tmp,0,sizeof tmp);        memset(h,-1,sizeof h);        en=0;        int n;        scanf("%d",&n);        for (int i=1;i<=n;++i)            for (int j=1;j<=n;++j)                scanf("%d",&a[i][j]);        s=0,t=n*n+1;cnt=0;        for (int i=1;i<n;++i)            for (int j=1;j<n;++j)                tmp[i][j]=++cnt;        for (int i=1;i<n;++i)            add(s,tmp[i][1],a[i][1]);        for (int i=1;i<n;++i)            add(s,tmp[n-1][i],a[n][i]);        for (int i=1;i<n;++i)            add(tmp[1][i],t,a[1][i]);        for (int i=1;i<n;++i)            add(tmp[i][n-1],t,a[i][n]);        for (int i=n-1;i>=2;--i)            for (int j=1;j<n;++j)            {                if (j+1<n) add(tmp[i][j],tmp[i][j+1],a[i][j+1]),add(tmp[i][j+1],tmp[i][j],a[i][j+1]);                if (i>=2) add(tmp[i][j],tmp[i-1][j],a[i][j]),add(tmp[i-1][j],tmp[i][j],a[i][j]);            }        SPFA();    }}
0 0
原创粉丝点击