洛谷月赛 SAC#1 - ACOJ云评测计划

题目描述

ACOJ的服务器简直是差到了一个令人发指的地步。于是SAC的出题人,也就是傻逼SOL,不得不强制要求每一个通过下载ACOJ软件包而搭建的分站,都为主站启动云端评测服务。
云评测服务是由网络来连接的。这样的网络连接是双向的;但是由于地理位置等因素的限制,并不是任意两台服务器都可以直接相连。ACOJ主站已经得到了可以直连的服务器的表,其中包含n个分站(包括主站)以及它们的m条连接情况,可以根据这个来分配各个分站的任务。
有一些分站的服主是SOL的脑残粉。他们会无条件地将他们的服务器提供给SOL。这些ACOJ分站称作“好站”。但是还有一些分站的服主是SOL黑。他们虽然拿到了ACOJ的服务端,但是并不愿意为SOL提供资源,于是利用黑科技关掉了云服务。也就是说,虽然主站仍然认为这些站点存在,但是它们不会起到任何作用——既不能传递通信,也不能进行评测。它们称作“坏站”。
经过千辛万苦的调查,SOL确定了ACOJ云评测系统中有最多k个坏站存在,而且这k个坏站似乎会使得ACOJ的云网络不再联通!大危机!
但是SOL太弱智了,并不能确定是哪k个。于是他请你来帮他找出任意一组可能会使得网络不再联通的k个站点,以便加强防范。

输入输出格式

输入格式:

输入包含m+1行。
第1行3个整数n、m、k。
接下来m行,每行两个整数a、b,表示标号为a和b的站点可以直接相连。

输出格式:

输出包含1行。
不超过k个整数,表示能够将原图割开的任意一组节点组合。
因为使用了Special Judge,所以节点的顺序并不用担心。只需要满足能够割开原图即可。
如果不存在这样的站点集合,输出“How oversuspicious you are, SOL!”;如果网络不存在任何坏站时本来就无法连通,输出“Poor SOL!”。

输入输出样例

输入样例#1:

4 4 2
1 2
2 3
3 4
4 1

输出样例#1:

1 3

输入样例#2:

4 6 2
1 2
2 3
3 4
4 1
1 3
2 4

输出样例#2:

How oversuspicious you are, SOL!

输入样例#3:

4 0 2

输出样例#3:

Poor SOL!

看完题发现是个np问题,然而发现k <= 3╮(╯▽╰)╭,于是就上大讨论术然后大力暴力于是就过了233.
代码如下

#include
#include
#include
#include
using namespace std;
const int sz = 60100;
int head[sz],nxt[sz],l[sz];
int dfn[501],low[501],dfs_clock;
bool is_cut[501];
int tot = 1,n,m,k;
bool use[501],vis[501];
void build_edge(int f,int t)
{
    l[tot] = t;
    nxt[tot] = head[f];
    head[f] = tot ++;
}
int tarjan(int u,int fa)
{
    int child = 0;
    dfn[u] = low[u] = ++ dfs_clock;
    for(int i = head[u] ; i ; i = nxt[i])
    {
        int v = l[i];
        if(!dfn[v] && !use[v])
        {
            child ++;
            low[v] = tarjan(v,u);
            low[u] = min(low[u],low[v]);
            if(low[v] >= dfn[u])
                is_cut[u] = 1;
        }
        else if(v != fa && dfn[v] < low[u] && !use[v])
            low[u] = dfn[v];
    }
    if(fa == 0 && child == 1)
        is_cut[u] = 0;
    return low[u];
}
int read()
{
    int x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while('0' <= in && in <= '9')
    {
        x = x * 10 + in - '0';
        in = getchar();
    }
    return x * f;
}
void init()
{
    dfs_clock = 0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(is_cut,0,sizeof(is_cut));

}
void dfs(int u)
{
    vis[u] = 1;
    for(int i = head[u] ; i ; i = nxt[i])
        if(!use[l[i]] && !vis[l[i]])
            dfs(l[i]);
    return ;
}
int main()
{
    n = read() , m = read() , k = read();
    for(int i = 1 ; i <= m ; i ++)
    {
        int f = read() , t = read();
        build_edge(f,t);
        build_edge(t,f);
    }
    {
        int ans = 0;
        for(int i = 1 ; i <= n ; i ++)
            if(!vis[i])
                dfs(i),ans ++;
        if(ans > 1)
        {
            puts("Poor SOL!");
            return 0;
        }
    }
    if(k == 1)
    {
        tarjan(1,0);
        for(int i = 1 ; i <= n ; i ++)
            if(is_cut[i])
            {
                printf("%d\n",i);
                return 0;
            }
    }
    if(k == 2)
    {
        for(int i = 1 ; i <= n ; i ++)
        {
            init();
            use[i] = 1;
            for(int j = 1 ; j <= n ; j ++)
                if(!use[j])
                {
                    tarjan(j,0);
                    break;
                }
            use[i] = 0;
            for(int j = 1 ; j <= n ; j ++)
                if(j != i && is_cut[j])
                {
                    printf("%d %d\n",i,j);
                    return 0;
                }
        }
    }
    if(k == 3)
    {
        for(int i = 1 ; i <= n ; i ++)
        {
            for(int j = i + 1 ; j <= n ; j ++)
            {
                init();
                use[i] = 1 , use[j] = 1;
                for(int k = 1 ; k <= n ; k ++)
                    if(!use[k])
                    {
                        tarjan(k,0);
                        break;
                    }
                use[i] = 0 , use[j] = 0;
                for(int k = 1 ; k <= n ; k ++)
                    if(k != i && k != j && is_cut[k])
                    {
                        printf("%d %d %d\n",i,j,k);
                        return 0;
                    }
            }
        }
    }
    puts("How oversuspicious you are, SOL!");
    return 0;
}
/*
6 7 1
1 2
1 3
1 4
2 5
3 5
4 5
5 6
*/

你可能感兴趣的:(题解,图论,tarjan)