• luogu P2746 [USACO5.3]校园网Network of Schools 题解


    前言:

    火星题。。。
    但是我调了半天,最后看了题解才明白。
    Wtcl

    解析:

    显然先缩个点。
    第一问,就是问多少入度为0的点。
    第二问,抽象一下就是要添加一些边,让一个DAG变成一个SCC,求最小边数。
    答案就是max(入度0的数量,出度0的数量)
    震惊,我竟然没看出来,活到爆!
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1000000+10;
    #define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
    #define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
    char buf[1 << 20], *p1, *p2;
    int n,cnt,tot,top,ss,Time,sss;
    struct node{
    	int to,nxt;
    }edge[maxn<<1];
    int head[maxn],belong[maxn],dfn[maxn],low[maxn],Stack[maxn],ind[maxn],outd[maxn];
    bool vis[maxn];
    void add(int from,int to){
    	edge[++cnt].to=to;
    	edge[cnt].nxt=head[from];
    	head[from]=cnt;
    }
    void tarjan(int u){
    	if(dfn[u]) return;
    	dfn[u]=low[u]=++Time;
    	vis[u]=1;
    	Stack[++top]=u;
    	for(int i=head[u];i;i=edge[i].nxt){
    		int v=edge[i].to;
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}else if(vis[v]) low[u]=min(low[u],dfn[v]);
    	}
    	if(dfn[u]==low[u]){
    		tot++;
    		while(Stack[top+1]!=u){
    			int t=Stack[top];
    			top--;
    			vis[t]=0;
    			belong[t]=tot;
    		}
    	}
    }
    void Solve(){
    	scanf("%d",&n);
    	for(int i=1,x;i<=n;++i){
    		while(1){
    			scanf("%d",&x);
    			if(x==0) break;
    			add(i,x);
    		}
    	}
    	for(int i=1;i<=n;++i) tarjan(i);
    	for(int u=1;u<=n;++u){
    		for(int i=head[u];i;i=edge[i].nxt){
    			int v=edge[i].to;
    			if(belong[u]==belong[v]) continue;
    			ind[belong[v]]++;
    			outd[belong[u]]++;
    		}
    	}
    	for(int i=1;i<=tot;++i) if(ind[i]==0) ss++;
    	for(int i=1;i<=tot;++i) if(outd[i]==0) sss++;
    	int ans;
    	if(tot==1) ans=0;
    	else ans=max(ss,sss);
    	printf("%d
    %d
    ",ss,ans);
    }
    int main(){
    	Solve();
    	return 0;
    }
    
    
    
  • 相关阅读:
    下一座“金矿”:移动医疗的契机和风险
    android ViewStub简单介绍
    IT人员必须掌握的10项软技能
    Android ListView item 点击事件失效问题的解决
    前端之Android入门(3):MVC模式(上)
    Android 错误提示: Can't create handler inside thread that has not called Looper.prepare()
    Android 性能优化提示
    Android 学习资源
    元素水平对齐
    div垂直居中
  • 原文地址:https://www.cnblogs.com/wwcdcpyscc/p/13878799.html
Copyright © 2020-2023  润新知