BZOJ 2438: [中山市選2011]殺人遊戲

這是要被市選艹爆的節奏啊。。。
discuss裏面也說了。。 輸出的是一個概率,等於1.0-“最少查證的人數”/“總人數”

其實就是縮個點 統計入度爲0的連通塊 這個就是最少查證人數了
然後discuss有組數據會很良心地提醒你
其實可以省一個點不問
如果有一個大小爲1的連通塊且它入度爲0、無出度或者連到的連通塊都還有別人連向它
那它就可以不選 ans–

這裏寫圖片描述
不知道爲啥就rank1了 233

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+2;
char B[1<<14],*S=B,*T=B;
#define gc (S==T&&(T=(S=B)+fread(B,1,1<<14,stdin),S==T)?-1:*S++)
inline int read(){
    int x=0,f=1; char ch=gc;
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}
    while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=gc;}
    return x*f;
}
struct edge{int x,y,nex;}a[N*3]; int len,fir[N];
void ins(int x,int y){
    a[++len]=(edge){x,y,fir[x]},fir[x]=len;
}
int dfn[N],low[N],id,sz[N],cnt;
bool v[N]; int in[N],st[N],tp,bl[N];
void dfs(int x){
    dfn[x]=low[x]=++id,st[++tp]=x,v[x]=1;
    for(int k=fir[x];k;k=a[k].nex){
        int y=a[k].y;
        if(!dfn[y])dfs(y),low[x]=min(low[x],low[y]);
        else if(v[y])low[x]=min(low[x],dfn[y]);
    }
    if(low[x]==dfn[x]){
        int i; cnt++;
        do{
            i=st[tp--],bl[i]=cnt,sz[cnt]++,v[i]=0;
        }while(i!=x);
    }
}
int main(){
    int n=read(),m=read(),i;
    for(i=1;i<=m;++i){
        int x=read(),y=read(); ins(x,y);
    }
    for(i=1;i<=n;++i)if(!dfn[i])dfs(i);
    for(i=1;i<=m;++i)
        if(bl[a[i].x]!=bl[a[i].y]) in[ bl[a[i].y] ]++;
    int s=0;
    for(i=1;i<=cnt;++i)if(!in[i])++s;
    bool u=0;
    for(i=1;i<=n;++i)
        if(sz[bl[i]]==1 && !in[bl[i]]){
            bool ok=1;
            for(int k=fir[i];k;k=a[k].nex)
                if(in[bl[a[k].y]]==1){ok=0; break;}
            if(ok){u=1; break;}
        }
    s-=u;
    printf("%.6lf\n",1.0-(double)s/n);
    return 0;
}

發佈了173 篇原創文章 · 獲贊 203 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章