zoukankan      html  css  js  c++  java
  • [NOIP2015] 信息传递

    题意:

    给你一个有向图,要你找到图中的最小环。

    题解:

    呵呵,去年联赛前做了这道题,连图都不会存;

    今年联赛前终于可以秒切了......

    tarjan求出最小的非单个点的强连通分量就好了;

    好像还可以用拓扑排序那套理论加上dfs求,嗯,腻害;

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 200010
    using namespace std;
    
    int n,dep,ans=1<<30,e_num,top,cnt;
    int nxt[N<<1],to[N<<1],h[N],dfn[N],low[N],stk[N],bl[N],num[N];
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1;
      while(ch>='0' && ch<='9') x=10*x+ch-'0',ch=getchar();
      return x*o;
    }
    
    void add(int x, int y) {
    	nxt[++e_num]=h[x],to[e_num]=y,h[x]=e_num;
    }
    
    void tarjan(int u) {
    	dfn[u]=low[u]=++dep;
    	stk[++top]=u;
    	for(int i=h[u]; i; i=nxt[i]) {
    		int v=to[i];
    		if(!dfn[v]) {
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}
    		else if(!bl[v]) low[u]=min(low[u],dfn[v]);
    	}
    	if(low[u]==dfn[u]) {
    		cnt++;
    		while(1) {
    			int v=stk[top--];
    			bl[v]=cnt,num[cnt]++;
    			if(v==u) break;
    		}
    	}
    }
    
    int main() {
     	n=gi();
    	for(int i=1; i<=n; i++) {
    		int x=gi();
    		add(i,x);
    	}
    	for(int i=1; i<=n; i++) {
    		if(!dfn[i]) tarjan(i);
    	}
    	for(int i=1; i<=cnt; i++) {
    		if(num[i]==1) continue;
    		ans=min(ans,num[i]);
    	} 
    	cout<<ans<<endl;
    	return 0;
    } 	
    
  • 相关阅读:
    word设置的密码忘了怎么办?
    Navicat Report Viewer 设置 HTTP 的方法
    如何处理Navicat Report Viewer 报表
    excel密码忘记了怎么办
    Beyond Compare文本比较搜索功能详解
    Popular Cows POJ
    Problem B. Harvest of Apples HDU
    网络流模型整理
    The Shortest Statement CodeForces
    Vasya and Multisets CodeForces
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7704473.html
Copyright © 2011-2022 走看看