• 5971 打击犯罪


    题目描述 Description

    某个地区有n(n<=1000)个犯罪团伙,当地警方按照他们的危险程度由高到低给他们编号为1-n,他们有些团伙之间有直接联系,但是任意两个团伙都可以通过直接或间接的方式联系,这样这里就形成了一个庞大的犯罪集团,犯罪集团的危险程度唯一由集团内的犯罪团伙数量确定,而与单个犯罪团伙的危险程度无关(该犯罪集团的危险程度为n)。现在当地警方希望花尽量少的时间(即打击掉尽量少的团伙),使得庞大的犯罪集团分离成若干个较小的集团,并且他们中最大的一个的危险程度不超过n/2。为达到最好的效果,他们将按顺序打击掉编号1到k的犯罪团伙,请编程求出k的最小值。

    输入描述 Input Description

     第一行一个正整数n。接下来的n行每行有若干个正整数,第一个整数表示该行除第一个外还有多少个整数,若第i行存在正整数k,表示i,k两个团伙可以直接联系。

    输出描述 Output Description

    一个正整数,为k的最小值

    样例输入 Sample Input

     7
        2 2 5
        3 1 3 4
        2 2 4
        2 2 3
        3 1 6 7
        2 5 7
        2 5 6

    样例输出 Sample Output

    1

     输出1(打击掉红色团伙

    数据范围及提示 Data Size & Hint

    n<=1000

    思路:逆向+分治

       这样退出来的一定是最小值

       具体为什么自己代入一组数据看看就全明白了

       非语言能形容

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 struct node
     6 {
     7     int u;
     8     int v;
     9     int w;
    10     int next;
    11 }edge[10001];
    12 int head[1001];
    13 int num=1;
    14 int map[1001][1001];
    15 int vis[10001];
    16 int tot;//记录每次搜索时所能搜索到的点的数量 
    17 int n;
    18 void add(int x,int y)
    19 {
    20     map[x][y]=1;
    21     map[y][x]=1;
    22 }
    23 void dfs(int x)
    24 {
    25     vis[x]=1;
    26     tot++;
    27     for(int i=1;i<=n;i++)
    28     {
    29         if(map[x][i]==1&&vis[i]==0)
    30         {
    31             dfs(i);
    32         }
    33     }
    34 }
    35 
    36 int main()
    37 {
    38 
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++)
    41     head[i]=-1;
    42     for(int i=1;i<=n;i++)
    43     {
    44         int m;
    45         scanf("%d",&m);
    46         for(int j=1;j<=m;j++)
    47         {
    48             int p;
    49             scanf("%d",&p);
    50             edge[num].u=i;
    51             edge[num].v=p;
    52             //edge[num].w=p;
    53             edge[num].next=head[i];
    54             head[i]=num++;
    55         }
    56     }
    57     /*for(int i=1;i<=n;i++)
    58     {
    59         int j=head[i];
    60         while(j!=-1)
    61         {
    62             cout<<edge[j].v<<" ";
    63             j=edge[j].next;
    64         }
    65         cout<<endl;
    66     }
    67     cout<<"********************************"<<endl;
    68     for(int i=1;i<=n;i++)
    69     {
    70         cout<<edge[head[i]].v<<endl;
    71     }*/
    72     for(int i=n;i>=1;i--)
    73     {
    74         int j=head[i];
    75         while(j!=-1)
    76         {
    77             if(edge[j].v>=i)
    78             {
    79                 add(edge[j].v,i);
    80                 tot=0;
    81                 memset(vis,0,sizeof(vis));
    82                 dfs(i);
    83                 if(tot>n/2)
    84                 {
    85                     cout<<i;
    86                     return 0;
    87                 }
    88             }
    89             j=edge[j].next;
    90         }
    91     }
    92     cout<<-1;
    93     return 0;
    94 }
  • 相关阅读:
    程序打包(通过VS2015插件 InstallShield2015 Limited Edition 方式)
    QSS单独设置四个边角
    Qt 设置窗口圆角
    Qt实现鼠标拖动窗口
    关于split切割的几种情况
    java开发过程中,报错Dangling meta character '*' near index 0,解决办法
    关于ArrayList的contains方法
    WPS文档按回车键不能换行怎么解决
    正则表达式截取数字
    如何用hibernate中查询出一个表数量总数
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6701014.html
Copyright © 2020-2023  润新知