• UVA12167 Proving Equivalences


    UVA12167 Proving Equivalences

    题意翻译
    题目描述 在数学中,我们常常需要完成若干命题的等价性证明。

    例如:有4个命题a,b,c,d,要证明他们是等价的,我们需要证明a<=>b,然后b<=>c,最后c<=>d。注意每次证明是双向的,因此一共完成了6次推导。另一种证明方法是:证明a->b,然后b->c,接着c->d,最后d->a,只须4次证明。

    现在你任务是证明 n 个命题全部等价,且你的朋友已经为你作出了m次推导(已知每次推导的内容),你至少还需做几次推导才能完成整个证明。

    输入数据 有T(T<=100)组数据,每组数据第一行为两个整数n和m(1<=n<=20000, 1<=m<=50000),即命题数和已完成的推导个数(编号为1..n)。以下m行每行包含两个整数s1和s2(1<=s1,s2<=n,s1!=s2),表明已经证明了s1->s2。

    输出数据 输出还需要做推导数的最小值。

    感谢@hicc0305 提供的翻译


    错误日志: 没有特判 (numc = 1) (即任意两点互通)时答案为 (0) 的情况


    Solution

    强联通分量搞成 (DAG) , 因为需要加边把图变为一个大强联通分量, 考虑出度和入度为 (0) 的点的数量, 这些点无法被到达或无法到达其他点, 输出计数的较大值即可满足所有点互达

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define cln(s, v) memset(s, v, sizeof(s))
    typedef long long LL;
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 1000019,INF = 1e9 + 19;
    int head[maxn],nume = 1;
    struct Node{
        int v,dis,nxt;
        }E[maxn << 3];
    void add(int u,int v,int dis){
        E[++nume].nxt = head[u];
        E[nume].v = v;
        E[nume].dis = dis;
        head[u] = nume;
        }
    int DFN[maxn], LOW[maxn], INDEX;
    int numc, col[maxn];
    bool ins[maxn];
    int S[maxn], top;
    void Tarjan(int u){
    	DFN[u] = LOW[u] = ++INDEX;
    	S[++top] = u;ins[u] = 1;
    	for(int i = head[u];i;i = E[i].nxt){
    		int v = E[i].v;
    		if(!DFN[v])Tarjan(v), LOW[u] = min(LOW[u], LOW[v]);
    		else if(ins[v])LOW[u] = min(LOW[u], DFN[v]);
    		}
    	if(DFN[u] == LOW[u]){
    		numc++;
    		while(S[top + 1] != u){
    			col[S[top]] = numc;
    			ins[S[top--]] = 0;
    			}
    		}
    	}
    int ing[maxn], outg[maxn];
    void init(){
    	cln(head, 0), nume = 1;
    	INDEX = 0, cln(DFN, 0), cln(LOW, 0);
    	cln(col, 0), numc = 0;
    	cln(ing, 0), cln(outg, 0);
    	}
    int T, num, nr;
    int main(){
    	T = RD();
    	while(T--){
    		init();
    		num = RD();nr = RD();
    		for(int i = 1;i <= nr;i++){
    			int u = RD(), v = RD();
    			add(u, v, 0);
    			}
    		for(int i = 1;i <= num;i++)if(!DFN[i])Tarjan(i);
    		if(numc == 1){printf("0
    ");continue;}
    		for(int u = 1;u <= num;u++){
    			for(int i = head[u];i;i = E[i].nxt){
    				int v = E[i].v;
    				if(col[u] != col[v]){
    					ing[col[v]]++;
    					outg[col[u]]++;
    					}
    				}
    			}
    		int in = 0, out = 0;
    		for(int i = 1;i <= numc;i++){
    			if(ing[i] == 0)in++;
    			if(outg[i] == 0)out++;
    			}
    		printf("%d
    ", max(in, out));
    		}
    	return 0;
    	}
    
  • 相关阅读:
    zsh: command not found: mysql
    ReactiveX -Rx
    mac 安装mysql
    mac 完全卸载mysql
    gradle 编译OutOfMemoryError
    Nginx均衡负载(IP_HASH)未生效
    Tomcat集群+Nginx+Redis服务搭建
    Spring之SpringMVC的RequestToViewNameTranslator(源码)分析
    Spring之SpringMVC的MethodNameResolver(源码)分析
    Spring之SpringMVC前端控制器DispatcherServlet(源码)分析
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9495271.html
Copyright © 2020-2023  润新知