L2-025 分而治之 (25 分) 数组模拟邻接表 map对道路判重,cnt数组模拟
Published on 2022-11-17 23:03 in 暂未分类 with 林动

L2-025 分而治之 (25 分) 数组模拟邻接表 map对道路判重,cnt数组模拟

    分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。

    输入格式:
    输入在第一行给出两个正整数 N 和 M(均不超过10 000),分别为敌方城市个数(于是默认城市从 1 到 N 编号)和连接两城市的通路条数。随后 M 行,每行给出一条通路所连接的两个城市的编号,其间以一个空格分隔。在城市信息之后给出参谋部的系列方案,即一个正整数 K (≤ 100)和随后的 K 行方案,每行按以下格式给出:

    Np v[1] v[2] … v[Np]
    其中 Np 是该方案中计划攻下的城市数量,后面的系列 v[i] 是计划攻下的城市编号。

    输出格式:
    对每一套方案,如果可行就输出YES,否则输出NO。

    看了下别人的答案似乎题目数据不会存在重边,不过题目没有明确说明而已,所以这题不使用map判重都行

    解法一:根据连边数来判断
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N=10005,M=N*2;
    int e[M],ne[M],h[N],idx;
    int cnt[N],backup[N];
    map<int,int> mp;
    
    void add(int a,int b)
    {
    	e[idx]=b;ne[idx]=h[a];h[a]=idx++;
    }
    
    int main()
    {
    	int n,m;
    	cin>>n>>m;
    	memset(h,-1,sizeof(h));
    	for(int i=0;i<m;++i)
    	{
    		int a,b;
    		cin>>a>>b;
    		if(mp[a]==b)
    		{
    			continue;
    		}
    		else
    		{
    			cnt[a]++;
    			cnt[b]++;
    			mp[a]=b;
    			mp[b]=a;
    			add(a,b);
    			add(b,a);
    		}
    		
    	} 
    	memcpy(backup,cnt,sizeof cnt);
    	int k;cin>>k;
    	while(k--)
    	{
    		memcpy(cnt,backup,sizeof cnt);
    		int np;cin>>np;
    		for(int i=0;i<np;++i)
    		{
    			int t;cin>>t;cnt[t]=0;
    			for(int i=h[t];i!=-1;i=ne[i])
    			{
    				int j=e[i];
    				cnt[j]--;
    			}
    		}
            bool flag=false;
    		for(int i=1;i<=n;++i)
    			if(cnt[i]>0){
    				flag=true;
    				break;
    			}
            if(flag)cout<<"NO"<<endl;
            else cout<<"YES"<<endl;
    	}
    	return 0;
    }
    
    解法二:dfs求连通块,如果连通块个数等于轰炸完剩余的城市数,说明剩余的城市都不联通
    #include <bits/stdc++.h>
    using namespace std;
    const int N=10005,M=N*2;
    int h[N],e[M],ne[M],idx;
    bool st[N];
    void add(int a,int b)
    {
    	e[idx]=b;ne[idx]=h[a];h[a]=idx++;
    }
    void dfs(int u){
    	st[u]=true;
    	for(int i=h[u];i!=-1;i=ne[i]){
    		int j=e[i];
    		if(st[j]==false)dfs(j);
    	}
    }
    int main()
    {
    	int n,m;cin>>n>>m;
    	memset(h,-1,sizeof h);
    	for(int i=0;i<m;++i)
    	{
    		int x,y;cin>>x>>y;
    		add(x,y);add(y,x);
    	}
    	int k;cin>>k;
    	while(k--){
    		memset(st,0,sizeof st);
    		int q,cnt=0;cin>>q;
    		for(int i=0;i<q;++i){
    			int x;cin>>x;
    			st[x]=1;
    		}
    		for(int i=1;i<=n;++i){
    			if(st[i]==false){
    				dfs(i);cnt++;
    			}
    		}
    		if(cnt==n-q)cout<<"YES"<<endl;
    		else cout<<"NO"<<endl;
    	}
    	return 0;
    }
    
    posted @   林动  阅读(15)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
    · 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
    · 【译】Visual Studio 中新的强大生产力特性
    · 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
    · 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
    点击右上角即可分享
    微信分享提示