这几天没有更新,给大家说声抱歉啦……你们的小酱仍然在进步,不会辜负大家的期望哒~
今天我们来做一道福建夏令营的题目,也算是继续学习信奥啦…也算是和@十一维的智子继续干架 继续学习。
题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由 nn 个点构成的无向图,nn 个点之间由 mm 条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入格式
第一行两个正整数,表示节点数和边数。接下来 mm 行,每行两个整数 u,vu,v表示点 uu 到点 vv 之间有道路相连。
输出格式
仅一行如果河蟹无法封锁所有道路,则输出 Impossible,否则输出一个整数,表示最少需要多少只河蟹。
输入输出样例
输入 #1
3 3
1 2
1 3
2 3
输出 #1
Impossible
输入 #2
3 2
1 2
2 3
输出 #2
1
说明/提示
【数据规模】
对于 100% 数据,1<=n<=104,1<=m<=105,保证没有重边。
首先,这都有疫情了你还遛个啥呀遛…是吧,所以小矿我先给河蟹点赞。
不过说回正题,这一题是一个好题。如果知道思路了,便会非常简单。但是如果不知道思路,却比较的难想出来。
我们来分析一下题目。首先,肯定要明确一点,那就是这个图是不一定联通的。于是,我们就可以将整张图切分成许多分开的连同子图来处理。然而最重要的事情是:如何处理一个连通图?
乍看下去,似乎无从下手,因为方案好像有很多种,根本就枚举不完。但是,关键要注意到题目中重要的两个条件,我们把它抽象成这两个要素:
①每一条边所连接的点中,至少要有一个被选中。②每一条边所连接的两个点,不能被同时选中。由此,可以推断出:
每一条边都有且仅有一个被它所连接的点被选中。
又因为我们要处理的是一个连通图。所以,对于这一个图的点的选法,可以考虑到相邻的点染成不同的颜色。
于是,对于一个连通图,要不就只有两种选法(因为可以全部选染成一种色的,也可以全部选染成另一种色的),要不就是impossible!
所以,我们只需要找到每一个子连通图,对它进行黑白染色,然后取两种染色中的最小值,然后最后汇总,就可以了。
另外,要判断impossible,只需要加一个used数组,记录已经遍历了哪些点。如果重复遍历一个点,且与上一次的颜色不同,则必然是impossible的。
所以我们还是看一下代码吧…
#include<cstdio>
#include<iostream>
#include<cmath>
#include<string>
#include<string>
#include<algorithm>
using namespace std;
struct Edge
{
int t;
int nexty;
}edge[200000];
int head[20000];
int cnt=0;
void add(int a,int b)
{
cnt++;
edge[cnt].t=b;
edge[cnt].nexty=head[a];
head[a]=cnt;
}
bool used[20000]={0};
int col[20000]={0};
int sum[2];
bool dfs(int node,int color)
{
if(used[node])
{
if(col[node]==color)
{
return true;
}
return false;
}
used[node]=true;
sum[col[node]=color]++;
bool tf=true;
for(int i=head[node];i!=0&&tf;i=edge[i].nexty)
{
tf=tf&&dfs(edge[i].t,1-color);
}
return tf;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(used[i])
{
continue;
}
sum[0]=sum[1]=0;
if(!dfs(i,0))
{
printf("Impossible");
return 0;
}
ans=ans+min(sum[0],sum[1]);
}
printf("%d",ans);
return 0;
}
还好吧,只要学过了图,应该就没问题了,只是要思考个…两三个小时吧。
在此,小酱向大家致歉!由于过年,连续几周没有更了,这对大家的期望及关注都是极大的消耗!因此,我们明天继续更新…
另:请大家继续关注@十一维的智子,有消息第一时间在留言板上留言,谢谢哟~