WA #1 求大佬调,感谢感谢
查看原帖
WA #1 求大佬调,感谢感谢
579961
JunBuJian楼主2022/7/25 20:38
#include <iostream>
#include <cstring>
#include <unordered_set>

using namespace std;
typedef long long LL;

const int N = 1e5 + 5,M = 6e5 + 4;
int h[N],hs[N],e[M],ne[M],idx;
int low[N],dfn[N],timestamp;
int stk[N],top,scc_cnt,id[N],din[N],Size[N],dout[N];
bool in_stk[N];

void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}

void addxx(int a,int b)
{
    e[idx] = b,ne[idx] = hs[a],hs[a] = idx ++;
}

void tarjan(int u)
{
    low[u] = dfn[u] = ++ timestamp;
    stk[++ top] = u,in_stk[u] = true;
    
    for(int i = h[u]; ~i ;i = ne[i])
    {
        int j = e[i];
        if(!dfn[j])
        {
            tarjan(j);
            low[u] = min(low[u],low[j]);
        }
        else if(in_stk[j]) low[u] = min(low[u],dfn[j]);
    }
    
    if(low[u] == dfn[u])
    {
        int y;
        ++ scc_cnt;
        
        do{
            y = stk[top --];
            id[y] = scc_cnt;
            in_stk[y] = false;
            Size[scc_cnt] ++;
        }while(y != u);
    }
}

bool check(int u)
{
    //首先这个联通的数量
    //看出度和入度
    if(din[u] == 0)
    {
        if(Size[u] == 1)
        {
            if(dout[u] == 0) return true;
            else {
                for(int i = hs[u]; ~i ;i = ne[i])
                  {
                      int j = e[i];
                      if(din[j] <= 1) return false;
                  }
                return true;  
            }
        }
    }
    return false;
}

int main()
{
    int n,m;
    cin >> n >> m;
    
    memset(h,-1,sizeof h);
    memset(hs,-1,sizeof hs);
    
    while(m --)
    {
        int a,b;
        cin >> a >> b;
        add(a,b);
    }
    
    for(int i = 1;i <= n;i ++)
       if(!dfn[i])
         tarjan(i);
    
    unordered_set<LL> q;
    
    for(int i = 1;i <= n;i ++)
      for(int j = h[i]; ~j ;j = ne[j])
      {
          int k = e[j];
          int a = id[i],b = id[k];
          LL hash = a * 10000000 + b;//哈希
          
          if(a != b && !q.count(hash))
          {
              din[b] ++;
              dout[a] ++;
              addxx(a,b);
          }
      }
      
    int cnt = 0;
    
    for(int i = 1;i <= scc_cnt;i ++)
        if(!din[i])
            cnt ++;
    
    for(int i = 1;i <= scc_cnt;i ++)
         if(check(i))
            {
                cnt --;
                break;
            }
    cout << cnt << endl;
    
    printf("%.6lf",1 - 1.00 * cnt / n);    
    return 0;
}
2022/7/25 20:38
加载中...