【week 5】作业博客

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; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值