1.[蓝桥杯 2013 国 C] 危险系数
思路:应该会有更优的解法,但是看这数据范围和题目难度,咳咳~~
就全部标记一次,都搜一遍。
上代码:
#include<bits/stdc++.h>
using namespace std;
int z,t;
const int MAXX=2000+10;
struct EVA{
int next,to;
}mapp[MAXX];
int head[MAXX],cnt=0;
void build(int u,int v){
mapp[++cnt].to=v;
mapp[cnt].next=head[u];
head[u]=cnt;
}
int qi,zhong;
bool ans=0,book[MAXX];
void dfs(int u){
if(u==zhong){
ans=1;
return ;
}
for(int i=head[u];i;i=mapp[i].next){
int v=mapp[i].to;
if(book[v] || ans)continue;
else book[v]=1,dfs(v),book[v]=0;
}
}
int ANS=0;
int main(){
cin>>z>>t;
for(int i=1;i<=t;i++){
int a,b;
cin>>a>>b;
build(a,b);
build(b,a);
}
cin>>qi>>zhong;
book[qi]=1;
dfs(qi);
book[qi]=0;
if(!ans){
cout<<"-1";
return 0;
}
for(int i=1;i<=z;i++){
if(i==qi || i==zhong)continue;
ans=0;
book[i]=1;
book[qi]=1;
dfs(qi);
book[qi]=0;
book[i]=0;
if(!ans)ANS++;
}
cout<<ANS;
return 0;
}
2.P3916 图的遍历
从高到低搜一遍,给当前的点带上标记,由于低等标记无法覆盖高等的标记,因此每个点只用搜一遍(BFS)
代码如下:
#include<bits/stdc++.h>
using namespace std;
int N,M;
const int MAXX=1e5+20;
int head[MAXX];
struct EVA{
int next,to;
}cjc[MAXX];
int cnt=0;
void build(int u,int v){
cjc[++cnt].to=v;
cjc[cnt].next=head[u];
head[u]=cnt;
}
int ANS[MAXX];
queue<int>eva;
int main(){
cin>>N>>M;
for(int i=1;i<=M;i++){
int a,b;
cin>>a>>b;
build(b,a);
}
for(int i=N;i>=1;i--){
if(ANS[i])continue;
eva.push(i);
while(!eva.empty()){
int wei=eva.front();
eva.pop();
ANS[wei]=i;
for(int j=head[wei];j;j=cjc[j].next){
int v=cjc[j].to;
if(ANS[v])continue;
else{
ANS[v]=i;
eva.push(v);
}
}
}
}
for(int i=1;i<=N;i++)cout<<ANS[i]<<" ";
return 0;
}
3.P1330 封锁阳光大学
思路:总体上的思路就是附上两种标记,每次遍历时都根据上次节点的标记赋值与该节点,若遇到已经赋值过的并与该点的值相同,则判定为失败。
其实如果学了环的话应该也能做,含有奇数元素的环则直接判为Impossible,所有的树都满足。
上代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int MAXX=100020;
struct EVA{
int to,next;
}cjc[MAXX*2];
int cnt=0,head[MAXX*2];
void build(int u,int v){
cjc[++cnt].to=v;
cjc[cnt].next=head[u];
head[u]=cnt;
}
queue<int>eva;
int book[MAXX];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
build(a,b);
build(b,a);
}
bool ANS=0;
int ans=0;
for(int i=1;i<=n;i++){
int js1=0,js2=0;
if(ANS)break;
if(book[i])continue;
book[i]=1;
eva.push(i);
while(!eva.empty()){
int wei=eva.front();eva.pop();
if(ANS)continue;
if(book[wei]==1)js1++;
else js2++;
for(int i=head[wei];i;i=cjc[i].next){
int v=cjc[i].to;
if(ANS)break;
if(book[v]){
if(book[v]==book[wei]){
ANS=1;
break;
}
continue;
}
else{
book[v]=(book[wei]==2?1:2);
eva.push(v);
}
}
}
ans+=min(js1,js2);
}
if(ANS){
cout<<"Impossible";
return 0;
}
cout<<ans;
return 0;
}