• bzoj2438: [中山市选2011]杀人游戏(强联通+特判)


    2438: [中山市选2011]杀人游戏

    题目:传送门 

    简要题意:

       给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率

    题解:
       一道非常好的题目!

       题目要知道最大的存活概率,那么也就是找到直接找到杀手的最小概率

       那么我们采用强联通缩点:

       统计每个联通分量的入度,如果入度为0(证明除此联通分量里的点,没有人可以知道连通分量里的信息,那就一定要先选一个人访问),那么sum++(因为依据题意,假如问到连通分量里的任意一个人,只要ta不是杀手,那么一定可以安全的遍历强联通分量里的所有人)

       接下来就是最关键的特判:

       对于连通分量里只有一个点的情况,如果它的入度为零,不一定就要访问(这里何前面似乎有些许矛盾)

       解释:如果有联通分量只有一个家族成员,并且没有入度,因为杀手只有一个,那么我们完全可以在遍历其他的n-1个点时得出答案(排除法嘛)

       但是它的出度不一定为0,所以还要判断一下在上面的基础上,这个点连出去的边是否能够被其他点访问(入度>1),很好理解吧

       如果以上的都满足,那么sum--

       还有一个小槽点:sum--一次就好了,因为如果有两种相同的情况,那么对于两个独立的点,我们还是要选择一个访问才能遍历完成的

       输出1.0-double(sum)/double(n)

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 int n,m;
      8 struct node
      9 {
     10     int x,y,next;
     11 }a[1110000];int len,last[510000];
     12 void ins(int x,int y)
     13 {
     14     len++;
     15     a[len].x=x;a[len].y=y;
     16     a[len].next=last[x];last[x]=len;
     17 }
     18 struct edge
     19 {
     20     int x,y,next;
     21 }e[1110000];int len1,last1[510000];
     22 void inss(int x,int y)
     23 {
     24     len1++;
     25     e[len1].x=x;e[len1].y=y;
     26     e[len1].next=last1[x];last1[x]=len1;
     27 }
     28 int cnt,tp,id;
     29 int belong[510000],dfn[510000],low[510000],sta[510000],size[510000];
     30 bool v[510000];
     31 void dfs(int x)
     32 {
     33     low[x]=dfn[x]=++id;
     34     sta[++tp]=x;v[x]=true;
     35     for(int k=last[x];k;k=a[k].next)
     36     {
     37         int y=a[k].y;
     38         if(dfn[y]==-1)
     39         {
     40             dfs(y);
     41             low[x]=min(low[x],low[y]);
     42         }
     43         else
     44         {
     45             if(v[y]==true)
     46                 low[x]=min(low[x],dfn[y]);
     47         }
     48     }
     49     if(low[x]==dfn[x])
     50     {
     51         int i;cnt++;
     52         do{
     53             i=sta[tp--];
     54             v[i]=false;
     55             belong[i]=cnt;
     56             size[cnt]++;
     57         }while(i!=x);
     58     }
     59 }
     60 int ru[510000],chu[510000],sum1,sum2;
     61 bool check(int x)
     62 {
     63     if(size[x]!=1)return true;
     64     if(last1[x]==0)return false;
     65     for(int k=last1[x];k;k=e[k].next)
     66     {
     67         int y=e[k].y;
     68         if(ru[y]<=1)return true;
     69     }
     70     return false;
     71 }
     72 int main()
     73 {
     74     cnt=tp=id=sum1=sum2=0;
     75     len=0;len1=0;
     76     memset(last,0,sizeof(last));memset(last1,0,sizeof(last1));
     77     scanf("%d%d",&n,&m);
     78     memset(chu,0,sizeof(chu));
     79     memset(ru,0,sizeof(ru));
     80     memset(sta,0,sizeof(sta));
     81     memset(dfn,-1,sizeof(dfn));
     82     memset(low,0,sizeof(low));
     83     memset(v,false,sizeof(v));
     84     for(int i=1;i<=m;i++)
     85     {
     86         int x,y;
     87         scanf("%d%d",&x,&y);
     88         ins(x,y);
     89     }
     90     for(int i=1;i<=n;i++)
     91         if(dfn[i]==-1)
     92             dfs(i);
     93     for(int i=1;i<=m;i++)
     94     {
     95         int st=belong[a[i].x],ed=belong[a[i].y];
     96         if(st!=ed)
     97         {
     98             ru[ed]++;
     99             inss(st,ed);
    100         }
    101     }
    102     for(int i=1;i<=cnt;i++)
    103         if(ru[i]==0)sum1++;
    104     for(int i=1;i<=cnt;i++)
    105         if(ru[i]==0)
    106             if(check(i)==false){sum1--;break;}
    107     printf("%.6lf
    ",1.0-double(sum1)/double(n));
    108     return 0;
    109 }
  • 相关阅读:
    oracle 存储过程 游标
    SQL DateTime查询与格式
    Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理
    C#命名规范
    (转)javascript——各种网页常用小技巧
    (转)WEB免费打印控件推荐
    JS倒计时代码
    使用重写 ajax 用的一些基础东西
    (转)动态加载CSS
    (转)用Javascript获取页面元素的位置
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8438040.html
Copyright © 2020-2023  润新知