题目描述

曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。

询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。

输入输出格式

输入格式:

 

第一行:两个整数N,M

接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。

 

输出格式:

 

仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。

 

输入输出样例

输入样例#1:  复制
3 3
1 2
1 3
2 3
输出样例#1:  复制
Impossible
输入样例#2:  复制
3 2
1 2
2 3
输出样例#2:  复制
1

说明

【数据规模】

1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。

 

思路是dfs每个联通块  分别黑白染色 ans+=min(黑,白)  

 

70ms

P1330 封锁阳光大学 DFS 随笔 第1张
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
const int N=10000+5;
int n,m;
vector<int> edge[N];
int vis[N];
int ok;
int ok1,ok2;

void dfs(int cur,int flag)
{
    vis[cur]=flag;
    if(flag==1)ok1++;
    else ok2++;

    if(edge[cur].size())
    rep(i,0,edge[cur].size()-1)
    {
        int v=edge[cur][i];
        if(vis[v]&&vis[v]!=flag)continue;
        if(vis[v]&&vis[v]==flag){ok=0;return ;}

        dfs(v,3-flag);
        if(!ok)return ;
    }
    return ;
}
int main()
{
    RII(n,m);
    rep(i,1,m)
    {
        int a,b;
        RII(a,b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    int ans=0;
    ok=1;
    rep(i,1,n)
    if(!vis[i])
    {
        ok1=0;
        ok2=0;
        dfs(i,1);
        ans+=min(ok1,ok2);
        if(ok==0)
            break;
    }
    if(!ok)printf("Impossible\n");
    else
    cout<<ans;
    return 0;
}
View Code

 

 

用前向星  45ms!!!比vector 快很多

P1330 封锁阳光大学 DFS 随笔 第3张
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
const int N=10000+5;
int n,m;
int vis[N];
int ok,ok1,ok2;

int head[N*20];
int cnt=1;
struct node
{
    int to;
    int nex;
}edge[N*20];

void add(int a,int b)
{
    edge[++cnt].to=b;
    edge[cnt].nex=head[a];
    head[a]=cnt;
}

void dfs(int cur,int flag)
{
    vis[cur]=flag;
    if(flag==1)ok1++;
    else ok2++;

    for(int i=head[cur];i;i=edge[i].nex)
    {
        int v=edge[i].to;
        if(vis[v]&&vis[v]!=flag)continue;
        if(vis[v]&&vis[v]==flag){ok=0;return ;}

        dfs(v,3-flag);
        if(!ok)return ;
    }
    return ;
}

int main()
{
    RII(n,m);
    rep(i,1,m)
    {
        int a,b;
        RII(a,b);
        add(a,b);
        add(b,a);
    }
    int ans=0;
    ok=1;
    rep(i,1,n)
    if(!vis[i])
    {
        ok1=0;
        ok2=0;
        dfs(i,1);
        ans+=min(ok1,ok2);
        if(ok==0)
            break;
    }
    if(!ok)printf("Impossible\n");
    else
    cout<<ans;
    return 0;
}
View Code

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄