• BZOJ1006: [HNOI2008]神奇的国度


    1006: [HNOI2008]神奇的国度

    Time Limit: 20 Sec  Memory Limit: 162 MB
    Submit: 3217  Solved: 1446
    [Submit][Status][Discuss]

    Description

      K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA
    相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2
    ...An之间仅存在N对认识关系:(A1A2)(A2A3)...(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,C
    D,DA相互认识,而AC,BD不认识.全民比赛时,为了防止做弊,规定任意一对相互认识的人不得在一队,国王相知道,
    最少可以分多少支队。

    Input

      第一行两个整数N,M。1<=N<=10000,1<=M<=1000000.表示有N个人,M对认识关系. 接下来M行每行输入一对朋

    Output

      输出一个整数,最少可以分多少队

    Sample Input

    4 5
    1 2
    1 4
    2 4
    2 3
    3 4

    Sample Output

    3

    HINT

      一种方案(1,3)(2)(4)

    Source

    题解:首先这是一道论文题,所以说还是先去读读论文,涨姿势比较好!

       你首先会了解什么是

       弦:连接不相邻的两个点的无向边

       弦图:对于一个大于3的环,存在至少一条弦

       团:一个图中的一些点集+相对应的边集是一个完全图

       单纯点:对于一个点u+与其相连接的v是一个团,则u是个单纯点

       引理:对于一个弦图至少存在一个一个单纯点,对于非完全图的弦图则至少存在两个

       

      对于此题来说一定是一个弦图,并且我们只要求出完美消除数列,再利用贪心即可

      此题论文中写的非常详细!

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    #define ld long double
    #define N 10005
    #define M 2000005
    using namespace std;
    int pre[M],v[M],now[N],p[N],bel[N],col[N],d[N],q[N];
    bool vis[N];
    int n,m,ans,tot;
    int read()
    {
        int x=0,f=1; char ch;
        while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1;
        while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
        return x*f;
    }
    void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; 
    } 
    int main()
    {
        n=read(); m=read();
        for (int i=1; i<=m; i++){
            int u=read(),v=read(); ins(u,v); ins(v,u);
        }
        for (int i=n; i; i--)
        {
            int t=0;
            for (int j=1; j<=n; j++) if (!vis[j] && d[j]>=d[t]) t=j;
            vis[t]=1; q[i]=t;
            for (int p=now[t]; p; p=pre[p]) {int son=v[p]; if (!vis[son]) d[son]++;}
        }
        ans=0;
        for (int i=n; i; i--)
        {
            int t=q[i];
            for (int p=now[t]; p; p=pre[p]) bel[col[v[p]]]=i;
            int j;
            for (j=1; ; j++) if (bel[j]!=i) break;
            col[t]=j;
            if (j>ans) ans=j;
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    error MSB8031(将vs2010的工程用vs2013打开时出的错)
    MFC如何使控件大小随着对话框大小自动调整
    基于MFC对话框程序中添加菜单栏 (CMenu)
    mfc改变对话框窗口大小
    MFC设置对话框大小
    uart与usart区别
    uart接口介绍和认识
    USB引脚属性
    使用百度云服务器BCC搭建网站,过程记录
    linux下文件的复制、移动与删除命令为:cp,mv,rm
  • 原文地址:https://www.cnblogs.com/HQHQ/p/6030864.html
Copyright © 2020-2023  润新知