社区讨论

蒟蒻求帮看代码。。

P4249[WC2007] 剪刀石头布参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi7wsj0m
此快照首次捕获于
2025/11/21 04:53
4 个月前
此快照最后确认于
2025/11/21 04:53
4 个月前
查看原帖
基本可以确定费用流没写错
CPP
#include<bits/stdc++.h>

using namespace std;

const int N=110;

int n;
int anss[110][110];
int u[N*N],v[N*N];

class Mincost
{
    private:
        static const int M=2000010;
        static const int N=100010;
        static const int inf=0x3f3f3f3f;

        struct Edge
        {
            int to,nxt,val,cost;

            Edge(){}
            Edge(int to,int nxt,int val,int cost):to(to),nxt(nxt),val(val),cost(cost){}
        }e[M*2];
        int head[N],cnt;
        int ans;

        void addedge(int u,int v,int val,int cost)
        {
            e[++cnt]=Edge(v,head[u],val,cost);
            head[u]=cnt;
        }

        int dis[N],pre[N],flow[N];
        bool vis[N];
        queue<int>q;

        bool SPFA(int s,int t)
        {
            memset(dis,0x3f,sizeof(dis));
            memset(pre,0,sizeof(pre));
            memset(flow,0x3f,sizeof(flow));
            dis[s]=0;
            q.push(s);
            vis[s]=1;
            while(!q.empty())
            {
                int now=q.front();
                q.pop();
                vis[now]=0;
                for(int i=head[now];i;i=e[i].nxt)
                {
                    if(!e[i].val) continue;
                    int vs=e[i].to,valn=e[i].cost;
                    if(dis[now]+valn<dis[vs])
                    {
                        dis[vs]=dis[now]+valn;
                        flow[vs]=min(flow[now],e[i].val);
                        pre[vs]=i;
                        if(!vis[vs])
                        {
                            q.push(vs);
                            vis[vs]=1;
                        }
                    }
                }
            }
            return pre[t];
        }

    public:
        Mincost():cnt(1),ans(0){}
        
        void insedge(int u,int v,int val,int cost)
        {
            addedge(u,v,val,cost);
            addedge(v,u,0,-cost);
        }

        int MCMF(int s,int t)
        {
            int res=0;
            while(SPFA(s,t))
            {
                int now=t,fl=flow[t];
                res+=fl;
                ans+=fl*dis[t];
                while(now!=s)
                {
                    e[pre[now]].val-=fl;
                    e[pre[now]^1].val+=fl;
                    now=e[pre[now]^1].to;
                }
            }
            return res;
        }

        int mincost(int s=0,int t=0)
        {
            if(ans) return ans;
            else
            {
                MCMF(s,t);
                return ans;
            }
        }

        void print(int l,int r)
        {
            for(int now=l;now<=r;now++)
            {
                for(int i=head[now];i;i=e[i].nxt)
                {
                    if(!e[i].val) 
                    {
                        anss[e[i].to][u[now-l+1]+v[now-l+1]-e[i].to]=0;
                        anss[u[now-l+1]+v[now-l+1]-e[i].to][e[i].to]=1;
                    }
                    else 
                    {
                        anss[u[now-l+1]+v[now-l+1]-e[i].to][e[i].to]=0;
                        anss[e[i].to][u[now-l+1]+v[now-l+1]-e[i].to]=1;
                    }
                }
            }
        }
}A;

//C(n,3)-\sigma C(d_i,2);

int outdgr[N];
int cnt=0;

int main()
{
    cin>>n;
    int s=n+n*n+1,t=s+1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int tmp;
            cin>>tmp;
            anss[i][j]=tmp;
            if(i>=j) continue;
            if(tmp==0) outdgr[i]++;
            if(tmp==1) outdgr[j]++;
            else
            {
                A.insedge(s,++cnt+n,1,0);
                A.insedge(cnt+n,i,1,0);
                A.insedge(cnt+n,j,1,0);
                u[cnt]=i,v[cnt]=j;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        A.insedge(s,i,outdgr[i],0);
        for(int j=0;j<n;j++)
        {
            A.insedge(i,t,1,j);
        }
    }
    cout<<n*(n-1)*(n-2)/6-A.mincost(s,t)<<'\n';
    A.print(n+1,n+cnt);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<anss[i][j]<<' ';
        }
        cout<<'\n';
    }
}

回复

1 条回复,欢迎继续交流。

正在加载回复...