UVALive5751 Safety Grade 无向图 全局最小割 SW算法

这道题有一个最大的坑点:

while(~scanf(“%d%d”,&n,&m))一直TLE,while(scanf(“%d%d”,&n,&m)==2)就AC了emmmmmm…

玄学。。太玄学了。。。

最小割用最大流算法可能会超时,SW算法更好一些,然而我不会。。。心情复杂.jpg

我果然还是太菜了啊55555…..

还有一点我一直在WA的是我用字符串读入,s[1]=u,s[3]=v,但是后来大佬提醒说u,v可能是两位数。。。豁然开朗Orz

附上AC代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;

const int MAX=102;
int n,m;
int v[MAX];
int a[MAX][MAX];
int dis[MAX];
bool vis[MAX];

int SW()
{
    int ans=INF;
    for(int i=0;i<n;i++)
        v[i]=i;
    while(n>1)
    {
        int maxp=1,prev=0;
        for(int i=1;i<n;i++)
        {
            dis[v[i]]=a[v[0]][v[i]];
            if(dis[v[i]]>dis[v[maxp]])
                maxp=i;
        }
        memset(vis,false,sizeof(vis));
        vis[v[0]]=true;
        for(int i=1;i<n;i++)
        {
            if(i==n-1)
            {
                ans=min(ans,dis[v[maxp]]);
                for(int j=0;j<n;j++)
                {
                    a[v[prev]][v[j]]+=a[v[j]][v[maxp]];
                    a[v[j]][v[prev]]=a[v[prev]][v[j]];
                }
                v[maxp]=v[--n];
            }
            vis[v[maxp]]=true;
            prev=maxp;
            maxp=-1;
            for(int j=1;j<n;j++)
                if(!vis[v[j]])
                {
                    dis[v[j]]+=a[v[prev]][v[j]];
                    if(maxp==-1||dis[v[maxp]]<dis[v[j]])
                        maxp=j;
                }
        }
    }
    return ans;
}

int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        if(m==0||n==0||n==1)
        {
            printf("0\n");
            continue;
        }
        memset(a,0,sizeof(a));
        char s[10];
        int u,v;char c;
        while(m--)
        {
            cin>>c>>u>>c>>v>>c;
            a[u][v]+=1;
            a[v][u]+=1;
        }
        int ans=SW();
        if(ans==INF)
            printf("0\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

 

点赞