zoukankan      html  css  js  c++  java
  • NOIP2015信息传递(拓扑排序 / 并查集)

    传送

    【题意】求最小环长

    【解题】我恨这个题

    我是一个没有读题的杀手傻手

    20分代码(单环)

    //第二题 
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector> 
    #include<queue>
    #define fr(i,n)  for( int i = 1; i <= n; ++i)
    
    const int N = 2e5 + 9;
    int idv[N],x,sum,n,son[N];
    
    std::queue<int>q;
    int main(){
        scanf("%d",&n);
        fr(i,n){
            scanf("%d",&x);
            idv[x]++;
            son[i] = x;
        }
        fr(i,n)  if(!idv[i]) { sum++; q.push(i); break;}
        while(!q.empty()){
            int x = q.front();
            q.pop();
            if(!idv[x]){
                //////////////////
                  int v = son[x];
                  idv[v]--;
                  if(idv[v] == 0){
                      sum++;
                      q.push(v);
                  }
                  else break;
              ///////////////////////    
            }
        }
        printf("%d",n - sum);
        return 0;
    }
    View Code

    60分代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector> 
    #include<queue>
    #define min(x,y) ((x)<(y)?(x):(y))
    #define fr(i,n)  for(register int i = 1; i <= n; ++i)
    const int N = 2e5 + 9;
    int idv[N],x,sum,ans = 0x3f3f3f,n,son[N],vis[N],temp;
    std::queue<int>q; 
    int main(){
        scanf("%d",&n);
        fr(i,n){
            scanf("%d",&x);
            idv[x]++;
            son[i] = x;
        }
        fr(i,n) if(!idv[i]){ idv[son[i]]--;} 
        fr(i,n){ 
            if (!vis[i] && idv[i] != 0){
                vis[i] = 1;
                temp = 1;
                int v = son[i];
                while (!vis[v]){ 
                    vis[v] = 1;
                    v = son[v];
                    temp++;
                }
                ans = min(ans,temp);
            }
        }
        printf("%d",ans);
        return 0;
    }
    View Code

    100分

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #define min(x,y) ((x)<(y)?(x):(y))
    using namespace std;
    const int N = 200050;
    int to[N],vis[N], idv[N];
    int n,ans,temp,j;
    queue <int> q;
    
    int main(){
        scanf("%d", &n);
        ans = n;
        for (int i = 1; i <= n; i++){
            scanf("%d", &to[i]);
            ++idv[to[i]];
        }
        for (int i = 1; i <= n; i++)
            if (idv[i] == 0){
                q.push(i);
                vis[i] = 1;
            }
            
        while (!q.empty()){
            int u = q.front();
            q.pop();
            --idv[to[u]];
            if (idv[to[u]] == 0) {
                vis[to[u]] = 1;
                q.push(to[u]);
            }  
        }
        
        for (int i = 1; i <= n; i++){ 
            if (!vis[i] && idv[i] != 0){
                vis[i] = 1;
                temp = 1;
                j = to[i];
                while (!vis[j]){ 
                    vis[j] = 1;
                    j = to[j];
                    temp++;
                }
                ans = min(ans,temp);
            }
        }
        
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    据说这题用并查集代码还会短,心态不爆炸的时候再来补吧。

  • 相关阅读:
    linux文件种类及其扩展名
    路由器终端常用linux命令汇总(持续更新)
    初识Makefile
    volatile关键字作用
    无言
    coredump文件抓取设置
    connect设置连接超时
    unix socket服务器
    交叉编译工具链制作
    编译选项说明
  • 原文地址:https://www.cnblogs.com/phemiku/p/11834912.html
Copyright © 2011-2022 走看看