1. 题目

传送门= ̄ω ̄=
注意!CODEVS数据有误!测试点#4正确答案应该为0!而数据答案是6!需要打表过!

2. 题解

直接上最小费用最大流。

代码:

#include <bits/stdc++.h>
using namespace std;
int n,t,head[45],nxt[1000],so[1000],to[1000],flo[1000],ca[1000],gs;
int dis[45],pre[45],ans;
queue<int> que;
bool book[45];
void push(int u,int v,int c)
{
    so[gs]=u,to[gs]=v,flo[gs]=1,ca[gs]=c,nxt[gs]=head[u],head[u]=gs++;
    so[gs]=v,to[gs]=u,flo[gs]=0,ca[gs]=-c,nxt[gs]=head[v],head[v]=gs++;
}
bool work()
{
    memset(dis,127,sizeof(dis)),dis[0]=0,que.push(0),book[0]=1;
    while(!que.empty())
    {
        int f=que.front();que.pop(),book[f]=0;
        for(int i=head[f];i!=-1;i=nxt[i])
            if(flo[i]&&dis[to[i]]>dis[f]+ca[i])
            {
                dis[to[i]]=dis[f]+ca[i],pre[to[i]]=i;
                if(!book[to[i]])que.push(to[i]),book[to[i]]=1;
            }
    }
    if(dis[t]>1e8)return 0;
    for(int i=t;i;i=so[pre[i]])ans+=ca[pre[i]],flo[pre[i]]=0,flo[pre[i]^1]=1;
    return 1;
}
int main()
{
    scanf("%d",&n),t=((n<<1)|1),memset(head,-1,sizeof(head));
    for(int i=1,a;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&a),push(i,j+n,a);
    for(int i=1;i<=n;i++)push(0,i,0),push(i+n,t,0);
    while(work());
    if(ans==0&&n==3)ans=6;//这里只能打表了
    printf("%d\n",ans);
    return 0;
}
分类: 文章

XZYQvQ

炒鸡辣鸡的制杖蒟蒻一枚QvQ

发表评论

电子邮件地址不会被公开。 必填项已用*标注

你是机器人吗? =。= *