zoukankan      html  css  js  c++  java
  • [中山市选2011]杀人游戏

    我考试想的正解,但是......
    有疏漏:
    1.邻接表的数组又开小了
    2.概率计算错误
    
    正解就是tarjen+乱搞
    
    1.这个图可能是分片的图,不一定是连通图
    2.对于其中的环进行缩点,然后在新建的图上找indegree为0的点的数量sum,就是我们需要调查的人(称之为张一帆)
    3.其中我们定义有 这样的张一帆,它可到的点的indegree都大于1 or 没有它可到的点 为自闭症张一帆
      那么如果一共有n-1个张一帆,1个自闭症张一帆,我们只需要调查n-1个张一帆
      不需要调查1个自闭症张一帆,因为n-1个张一帆不是,那么自闭症张一帆一定是杀手
    
    (ps:考试时脑子不太好使.....
         概率计算应该是同时计算,没有先后关系...)


      1 #include<cstdio>
      2 #include<cstring>
      3 #include<ctime>
      4 #include<queue>
      5 #include<algorithm>
      6 #include<iostream>
      7 #define dd double
      8 #define mem(a,b) memset(a,b,sizeof(a))
      9 using namespace std;
     10 const int N=100500;
     11 int minn(int a,int b){return a<b?a:b;}
     12 bool ok(int a,int b){return a>b;}
     13 int read()
     14 {
     15     int ans=0;char q=getchar();
     16     while(q<'0'||q>'9')q=getchar();
     17     while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
     18     return ans;
     19 }
     20 struct son
     21 {
     22     int v,next;
     23 };
     24 son a1[N<<2],ayuan[N<<2];
     25 int first[N<<2],firstyuan[N<<2],e,eyuan;
     26 void add(int u,int v)
     27 {
     28     a1[e].v=v;
     29     a1[e].next=first[u];
     30     first[u]=e++;
     31 }
     32 void addyuan(int u,int v)
     33 {
     34     ayuan[eyuan].v=v;
     35     ayuan[eyuan].next=firstyuan[u];
     36     firstyuan[u]=eyuan++;
     37 }
     38 
     39 int dfn[N],low[N],vis[N],now;
     40 int dui[N],sum,size[N];
     41 int zhan[N<<3],he;
     42 void tan(int x)
     43 {
     44     //printf("x=%d
    ",x);
     45     dfn[x]=low[x]=++now;
     46     zhan[++he]=x;vis[x]=1;
     47     for(int i=firstyuan[x];i!=-1;i=ayuan[i].next)
     48     {
     49         int temp=ayuan[i].v;
     50         //printf("temp=%d
    ",temp);
     51         if(dfn[temp]==-1)
     52         {
     53           tan(temp);
     54           low[x]=minn(low[x],low[temp]);
     55         }
     56         else
     57           if(vis[temp])
     58             low[x]=minn(low[x],dfn[temp]);
     59     }
     60     if(dfn[x]==low[x])
     61     {
     62         ++sum;int temp;
     63         while(1)
     64         {
     65             temp=zhan[he--];
     66             vis[temp]=0;
     67             dui[temp]=sum;
     68             ++size[sum];
     69             if(temp==x)
     70               break;
     71         }
     72     }
     73 }
     74 
     75 int n,m;
     76 int u,o,p,hh;
     77 int ind[N],zhen[N];
     78 int judge[N];
     79 bool flag[N];
     80 //好像只需找出真点 
     81 void dfs(int x,int fa)
     82 {
     83     if(judge[x]!=-2)
     84       zhen[fa]+=size[x];
     85     else
     86       return ;
     87     for(int i=first[x];i!=-1;i=a1[i].next)
     88         dfs(a1[i].v,fa);
     89 }
     90 
     91 dd mi(dd a,int c)
     92 {
     93     dd ans=1;
     94     while(c)
     95     {
     96         if(c&1)
     97           ans*=a;
     98         a=a*a;
     99         c>>=1;
    100     }
    101     return ans;
    102 }
    103 
    104 /*void out11()
    105 {
    106     printf("hh=%d sum=%d
    ",hh,sum);
    107     for(int i=1;i<=sum;++i)
    108       printf("%d ",zhen[i]);
    109     printf("
    ");
    110 }*/
    111 
    112 int main(){
    113     //freopen("killer7.in","r",stdin);
    114     //freopen("killer.out","w",stdout);
    115     //freopen("1.txt","r",stdin);
    116     mem(firstyuan,-1);
    117     mem(judge,-1);
    118     mem(dfn,-1);
    119     mem(first,-1);
    120     n=read();m=read();
    121     for(int i=1;i<=m;++i)
    122     {
    123         u=read();o=read();
    124         addyuan(u,o);
    125     }
    126     for(int i=1;i<=n;++i)
    127       if(dfn[i]==-1)
    128         tan(i);
    129     //cout<<0;
    130     
    131     for(int i=1;i<=n;++i)
    132     {
    133         for(int j=firstyuan[i];j!=-1;j=ayuan[j].next)
    134         {
    135             int temp=ayuan[j].v;
    136             if(dui[i]==dui[temp])continue;//不能自己连
    137             add(dui[i],dui[temp]);
    138             if(judge[dui[temp]]==-1)
    139               judge[dui[temp]]=dui[i];
    140             else
    141               if(judge[dui[temp]]!=dui[i]&&judge[dui[temp]]!=-2)
    142                 judge[dui[temp]]=-2;
    143         }
    144     }
    145     
    146     hh=0;
    147     
    148     for(int i=1;i<=sum;++i)
    149       if(judge[i]==-1)
    150       {
    151             dfs(i,i);
    152             ++hh;
    153         }
    154     sort(zhen+1,zhen+1+sum,ok);
    155     if(zhen[hh]==1)--hh;
    156     
    157     //cout<<hh;
    158     printf("%.6lf",1-hh*1.0/(dd)n);
    159     //while(1);
    160     return 0;
    161 }
    162     
    code
  • 相关阅读:
    重新点亮linux 命令树————网络配置的查看[十一三]
    重新点亮linux 命令树————网络管理[十一二]
    重新点亮linux 命令树————文件特殊权限[十一]
    重新点亮linux 命令树————权限的修改[十]
    重新点亮linux 命令树————文件权限和目录权限[九]
    重新点亮linux 命令树————用户和用户组的配置文件[八]
    重新点亮linux 命令树————su和sudo[七]
    综述|线结构光中心提取算法研究发展
    华为云服务功能总览
    国民技术芯片相关产业研发
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7247381.html
Copyright © 2011-2022 走看看