• luogu P1418 选点问题


    题目描述

    给出n个点,m条边,每个点能控制与其相连的所有的边,要求选出一些点,使得这些点能控制所有的边,并且点数最少。同时,任意一条边不能被两个点控制

    输入输出格式

    输入格式:

    第一行给出两个正整数n,m

    第2~m+1行,描述m条无向边

    每行给出x,y,表示一条无向边(x,y)

    输出格式:

    输出最少需要选择的点的个数,如果无解输出“Impossible”(不带引号)

    输入输出样例

    输入样例#1:
    7 5
    1 2
    1 3
    5 6
    6 7
    1 2
    输出样例#1:
    2

    说明

    【数据范围】

    对于30%的数据1<=n<=100

    对于100%的数据1<=n<=1000

    m<=n^2

    不保证图连通

    【题目来源】

    tinylic改编

    黑白染色,有多个联通块

    #include<cstdio>
    #include<queue>
    #include<cstdlib>
    using namespace std;
    
    #define N 100003
    struct node{
        int v,next;
    }edge[N*10];
    int head[N],n,m;int num=0;
    int vis[N];
    void add_edge(int x,int y)
    {
        edge[++num].v=y,edge[num].next=head[x];head[x]=num;
    }
    
    int ans,ans1,ans2;
    void dfs(int x)
    {
        if(vis[x]==1)ans1++;
        else if(vis[x]==2)ans2++;
        for(int i=head[x];i;i=edge[i].next)
        {
            int v=edge[i].v;
            if(vis[x]==vis[v])
            {
                puts("Impossible");exit(0);
            }
            if(!vis[v])
            {
                vis[v]=3-vis[x];
                dfs(v);        
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            add_edge(a,b);
            add_edge(b,a);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                vis[i]=1;
                ans1=ans2=0;
                dfs(i);
                ans+=min(ans1,ans2);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    android点滴 之 进度条
    android点滴(26)之让线程拥有自己的消息循环
    Python property
    MD5加密
    哈希表加载xml文件
    .NET自定义控件制作
    如何用Treeview树加载xml
    xml的属性
    FFT实现——有趣的移位寄存流水线形式
    频率选择滤波器 线性时不变系统
  • 原文地址:https://www.cnblogs.com/sssy/p/7071564.html
Copyright © 2020-2023  润新知