2 条题解

  • 0
    @ 2025-10-8 17:06:23
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    vector<int>G1[N], G2[N]; 
    int tsp, cnt, dfn[N], low[N], scc[N], num[N];
    stack<int> stk;bool instk[N];
    void tarjan(int x)
    {
    	dfn[x]=low[x]=++tsp;
    	stk.push(x);instk[x]=1;
    	for(int y:G1[x])
    	{
    		if(!dfn[y])
    		{
    			tarjan(y);
    			low[x]=min(low[x], low[y]);
    		}
    		else if(instk[y])low[x]=min(low[x], dfn[y]);
    	}
    	if(dfn[x]==low[x])
    	{
    		cnt++;
    		for(int z=-1;z!=x;)
    		{
    			z=stk.top();stk.pop();instk[z]=0;
    			scc[z]=cnt;
    			num[cnt]++;
    		}
    	}
    }
    
    int main()
    {
    	int n, m;scanf("%d%d", &n, &m);
    	for(int i=1, x, y; i <= m; i++)
    	{
    		scanf("%d%d", &x, &y);
    		G1[x].push_back(y);
    	}
    
    	tsp=cnt=0;memset(dfn, 0, sizeof(dfn));memset(low, 0, sizeof(low));
        memset(instk, 0, sizeof(instk));
    	memset(scc, 0, sizeof(scc));
    	memset(num, 0, sizeof(num));
    	for(int i=1;i <= n;i++)if(dfn[i]==0)tarjan(i);
    	
        map<pair<int, int>, bool>mp; vector<int>rd(cnt+1);
    	for(int i=1;i <= n;i++)for(int j:G1[i])
        {
            int x=scc[i], y=scc[j];
            if(x!=y && !mp[{x, y}])G2[x].push_back(y), rd[y]++, mp[{x, y}]=1;
        }
    		
    	int p=0;for(int i=1;i <= cnt;i++)if(!rd[i])p++;
    	
    	for(int i=1;i <= cnt;i++)if(num[i]==1 && rd[i]==0)
    	{
    		bool flag=0;
    		for(int j:G2[i])if(rd[j]==1){flag=1;break;}
    		if(!flag){p--;break;}
    	}
    	printf("%.6lf\n", 1.0 - 1.0*p/n );	
    	return 0;
    }
    
    • 0
      @ 2025-10-8 17:06:09
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e5+10;
      vector<int>G1[N],G2[N]; 
      int tsp,cnt,dfn[N],low[N],scc[N],num[N];
      stack<int> stk;bool instk[N];
      void tarjan(int x)
      {
      	dfn[x]=low[x]=++tsp;
      	stk.push(x);instk[x]=1;
      	for(int y:G1[x])
      	{
      		if(!dfn[y])
      		{
      			tarjan(y);
      			low[x]=min(low[x],low[y]);
      		}
      		else if(instk[y])low[x]=min(low[x],dfn[y]);
      	}
      	if(dfn[x]==low[x])
      	{
      		cnt++;
      		for(int z=-1;z!=x;)
      		{
      			z=stk.top();stk.pop();instk[z]=0;
      			scc[z]=cnt;
      			num[cnt]++;
      		}
      	}
      }
      
      int main()
      {
      	int n,m;scanf("%d%d",&n,&m);
      	for(int i=1,x,y;i<=m;i++)
      	{
      		scanf("%d%d",&x,&y);
      		G1[x].push_back(y);
      	}
      
      	tsp=cnt=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
          memset(instk,0,sizeof(instk));
      	memset(scc,0,sizeof(scc));
      	memset(num,0,sizeof(num));
      	for(int i=1;i<=n;i++)if(dfn[i]==0)tarjan(i);
      	
          map<pair<int,int>,bool>mp; vector<int>rd(cnt+1);
      	for(int i=1;i<=n;i++)for(int j:G1[i])
          {
              int x=scc[i],y=scc[j];
              if(x!=y && !mp[{x,y}])G2[x].push_back(y),rd[y]++,mp[{x,y}]=1;
          }
      		
      	int p=0;for(int i=1;i<=cnt;i++)if(!rd[i])p++;
      	
      	for(int i=1;i<=cnt;i++)if(num[i]==1 && rd[i]==0)
      	{
      		bool flag=0;
      		for(int j:G2[i])if(rd[j]==1){flag=1;break;}
      		if(!flag){p--;break;}
      	}
      	printf("%.6lf\n", 1.0 - 1.0*p/n );	
      	return 0;
      }
      • 1

      *【缩点】杀人游戏[中山市选2011]

      信息

      ID
      4103
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      161
      已通过
      22
      上传者