列表

详情


NC50402. 网络

描述

一个电话线公司(简称TLC)正在建立一个新的电话线缆网络,他们连接了若干个地点,编号分别从1到N,没有两个地点有相同的号码,这些线是双向的并且能使两个地点保持通讯,每个地点的线都终结于电话交换机。每个地点都有一个电话交换机。从每个地点都能通过线缆到达其他任意的地点,然而它并不需要直接连接,它可以通过若干个交换机来到达目的地。
有时候某个地点供电出问题时,交换机就会停止工作。TLC的工作人员意识到,除非这个地点是不可达的,否则这种情况就会发生,它还会导致一些其它的地点不能互相通讯。在这种情况下我们会称这个地点(错误发生的地方)为灾区。现在工作人员想要写一个程序统计所有灾区的数量。帮帮他们。

输入描述

输入文件包括若干组测试数据。
每一组是一个网络,每一组测试数据的第一行是地点的总数量N。每组接下来最多有N行包括一个数字表示一个地点和与它相连接的地点的数字。最多N行可以完全描述整个网络,比如,网络中每个直接连接的两个地点被至少一行包括。一行内的所有数字都要用空格隔开。每组数据需要用单独的一个0结束。最后的块只有一行即N=0。

输出描述

输出除了最后一组,其他每一组的灾区的数量,每个块用一行输出。

示例1

输入:

5
5 1 2 3 4
0
6
2 1 3
5 4 6 2
0
0

输出:

1
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java 解法, 执行用时: 336ms, 内存消耗: 19780K, 提交时间: 2021-09-21 16:10:24

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String args[]){
        new Thread(null, () -> new Main().solve(), "1", (1 << 30)).start();
    }
    Scanner in;
    PrintWriter out;
    public void solve(){
        in = new Scanner(System.in);
        out = new PrintWriter(System.out);
        go();
    }


    int s[];
    int ll[];
    int rr[];

    int setv[];
//    void build(int id,int left,int right){
//        if(left==right){
//            s[id] = 1;
//            ll[id] = rr[id] = wt[pt[left]];
//            return;
//        }
//        int mid = (left+right)/2;
//        build(id*2,left,mid);
//        build(id*2+1,mid+1,right);
//        s[id] = s[id*2] + s[id*2+1];
//        if(rr[id*2]==ll[id*2+1]){
//            s[id]--;
//        }
//        rr[id] = rr[id*2+1];
//        ll[id] = ll[id*2];
//
//    }
//
//    long[] qry(int id,int left,int right,int l,int r){
//        if(left>=l&&right<=r){
//            return new long[]{s[id],ll[id],rr[id]};
//        }else if(left>r||right<l){
//            return new long[]{0,-1,-1};
//        }
//        int mid = (left+right)/2;
//
//        if(setv[id]!=-1){
//            setv[id*2] = setv[id*2+1] =  setv[id];
//            ll[id*2]=rr[id*2]=ll[id*2+1]=rr[id*2+1] = setv[id];
//            s[id*2] = s[id*2+1] = 1;
//            setv[id] = -1;
//        }
//
//
//        long v1[] = qry(id*2,left,mid,l,r);
//        long v2[] = qry(id*2+1,mid+1,right,l,r);
//        s[id] = s[id*2] + s[id*2+1];
//        if(rr[id*2]==ll[id*2+1]){
//            s[id]--;
//        }
//        rr[id] = rr[id*2+1];
//        ll[id] = ll[id*2];
//        if(v1[0]==0){
//            return v2;
//        }else if(v2[0]==0){
//            return v1;
//        }
//
//
//        long add = 0;
//        if(v1[2]==v2[1]){
//            add = -1;
//        }
//        long le = v1[1];
//        long ri = v2[2];
//
//        return new long[]{v1[0]+v2[0]+add, le, ri};
//    }

//    void update(int id,int left,int right,int l,long val){
//        if(left>l||right<l){
//            return;
//        }else if(left==right){
//            s[id] += val;
//            return;
//        }
//        int mid = (left+right)/2;
//        if(mx[id]!=0){
//            mx[id*2] += mx[id];
//            mx[id*2+1] += mx[id];
//
//            s[id*2] += mx[id]*(mid-left+1);
//            s[id*2+1] += mx[id]*(right-(mid+1)+1);
//
//
//            mx[id] = 0;
//        }
//
//        update(id*2,left,mid,l,val);
//        update(id*2+1,mid+1,right,l,val);
//        s[id] = s[id*2] + s[id*2+1];
//
//    }

//    void update(int id,int left,int right,int l,int r,long val){
//        if(left>r||right<l){
//            return;
//        }else if(left>=l&&right<=r){
//            setv[id] = val;
//            ll[id]  = val;
//            rr[id]  = val;
//            s[id] = 1;
//            return;
//        }
//        int mid = (left+right)/2;
//        if(setv[id]!=-1){
//            setv[id*2] = setv[id*2+1] =  setv[id];
//            ll[id*2]=rr[id*2]=ll[id*2+1]=rr[id*2+1] = setv[id];
//            s[id*2] = s[id*2+1] = 1;
//            setv[id] = -1;
//        }
//
//        update(id*2,left,mid,l,r,val);
//        update(id*2+1,mid+1,right,l,r,val);
//        s[id] = s[id*2] + s[id*2+1];
//        if(rr[id*2]==ll[id*2+1]){
//            s[id]--;
//        }
//        rr[id] = rr[id*2+1];
//        ll[id] = ll[id*2];
//
//    }



    int h[],ne[],to[],wt[],c[];
    int ct = 0;
    void add(int u,int v){
        to[ct] = v;
        ne[ct] = h[u];
        h[u] = ct++;
    }
    int n;

    int time = 0;
    int top = 0;
    int low[];
    boolean iscut[];
    int res=  0;
    void tarjanNonDirect(int u) {
        low[u] = dfn[u]= ++time;
        stk[top++] = u;
        int child = 0;
        for(int i=h[u];i!=-1;i=ne[i]) {
            int v = to[i];
            if(dfn[v]==0) {
                tarjanNonDirect(v);
                low[u]=Math.min(low[u],low[v]);
                if(low[v]>=dfn[u]){
                    if(u!=0||++child>1){
                        iscut[u] = true;

                    }
                }
            } else {
                low[u] = Math.min(low[u],dfn[v]);

            }
        }
    }


    void go() {

        while (true) {
            time = 0;
            top = 0;
            res = 0;
            ct = 0;
            n = in.nextInt();
            if (n == 0) {
                out.close();
                return;
            }
            //  int q = in.nextInt();
            h = new int[n];
            Arrays.fill(h, -1);
            ne = new int[n*n+100];
            to = new int[n*n+100];
            wt = new int[n];

            fa = new int[n];
            dep = new int[n];
            //top = new int[n];
            son = new int[n];
            sz = new int[n];
            Arrays.fill(sz, 1);
            dfn = new int[n];
            pt = new int[n];
            gpt = new int[n];
            stk = new int[n];
            c = new int[n];
            iscut = new boolean[n];
            low = new int[n];


            while (true) {
                int f = in.nextInt();
                if (f == 0) {
                    break;
                }
                String y[] = in.nextLine().split(" ");
                for (String jj : y) {
                    if("".equals(jj)) continue;
                    int p = Integer.parseInt(jj);
                    add(p - 1, f - 1);
                    add(f - 1, p - 1);
                }



            }
            tarjanNonDirect(0);
            res = 0;
            for(int j=0;j<n;++j){
                if(iscut[j]){
                    res++;
                }
            }
            out.println(res);

        }


//        for(int i= 0;i<n;++i){
//            c[i] = in.nextInt();
//            wt[i] = in.nextInt();
//        }


//        for(int i=0;i<n-1;++i){
//            int u = in.nextInt()-1;
//            int v = in.nextInt()-1;
//            add(u,v);
//            add(v,u);
//        }


        //   dfs1(0);
        //   dfs2(0);
        //    treeLink(0);

//        for(int i=0;i<n;++i){
//            f[i] = wt[pt[i]];
//        }
//        s = new int[n*4];
//        ll = new int[n*4];
//        rr = new int[n*4];
//        setv = new int[n*4];
//        Arrays.fill(setv,-1);
//
//        build(1,0,n-1);
//
//        for(int i=0;i<q;++i){
//            String c = in.next();
//
//            if("C".equals(c)){
//                int u = in.nextInt()-1;
//                int v = in.nextInt()-1;
//                int w = in.nextInt();
//                while(top[u]!=top[v]){
//                    if(dep[top[u]]>=dep[top[v]]){
//                        update(1,0,n-1,dfn[top[u]],dfn[u],w);
//                        u = fa[top[u]];
//                    }else{
//                        update(1,0,n-1,dfn[top[v]],dfn[v],w);
//                        v = fa[top[v]];
//                    }
//                }
//
//                if(dep[u]>=dep[v]){
//                    update(1,0,n-1,dfn[v],dfn[u],w);
//                }else{
//                    update(1,0,n-1,dfn[u],dfn[v],w);
//                }
//            }else{
//                int u = in.nextInt()-1;
//                int v = in.nextInt()-1;
//                long lu = -1000;
//                long lv = -1000;
//                long r= 0;
//                while(top[u]!=top[v]){
//                    if(dep[top[u]]>=dep[top[v]]){
//                        long p[] = qry(1,0,n-1,dfn[top[u]],dfn[u]);
//                        r += p[0];
//                        if(lu==p[2]){
//                            r--;
//                        }
//                        u = fa[top[u]];
//                        lu = p[1];
//                    }else{
//                        long p[] = qry(1,0,n-1,dfn[top[v]],dfn[v]);
//                        r += p[0];
//                        if(lv==p[2]){
//                            r--;
//                        }
//                        v = fa[top[v]];
//                        lv = p[1];
//                    }
//                }
//                if(dep[u]>=dep[v]){
//                    long p[] = qry(1,0,n-1,dfn[v],dfn[u]);
//                    r += p[0];
//
//                        if (p[1] == lv) {
//                            r--;
//                        }
//                        if (p[2] == lu) {
//                            r--;
//                        }
//
//                }else{
//                    long p[] = qry(1,0,n-1,dfn[u],dfn[v]);
//                    r += p[0];
//
//                        if (p[1] == lu) {
//                            r--;
//                        }
//                        if (p[2] == lv) {
//                            r--;
//                        }
//
//
//
//                }
//                out.println(r);
//
//            }
//        }

      //  out.close();

    }

    int fa[],dep[],son[],sz[],dfn[],pt[],gpt[],stk[];
//    void dfs1(int rt){
//        sz[rt] = 1;
//        for(int i=h[rt];i!=-1;i=ne[i]){
//            int v = to[i];
//            if(v==fa[rt]) continue;
//            fa[v] = rt;
//            dep[v] = dep[rt] + 1;
//            dfs1(v);
//            sz[rt] += sz[v];
//            if(son[rt]==0||sz[son[rt]]<sz[v]){
//                son[rt] = v;
//            }
//        }
//    }
//    int id = 0;
//    void dfs2(int rt){
//        dfn[rt] = id;
//        pt[id++] = rt;
//        if(son[rt]!=0){
//            top[son[rt]] = top[rt];
//            dfs2(son[rt]);
//        }
//        for(int i=h[rt];i!=-1;i=ne[i]){
//            int v = to[i];
//            if(v==fa[rt]||v==son[rt]) continue;
//            top[v] = v;
//            dfs2(v);
//        }
//    }
//
//    public void treeLink(int ort){
//        int p = 0;
//        stk[p++] = ort;
//        int clock = 0;
//        int rt = -1;
//        while(p>0) {
//            rt = stk[--p];
//            gpt[clock++] = rt;
//            for (int i = h[rt]; i != -1; i = ne[i]) {
//                int v = to[i];
//                if (fa[rt] == v) continue;
//                fa[v] = rt;
//                dep[v] = dep[rt] + 1;
//                stk[p++] = v;
//            }
//        }
//        for(int i=n-1;i>0;--i){
//            int cur = gpt[i];
//            int fat = fa[cur];
//            sz[fat] += sz[cur];
//            if (son[fat]== 0 || sz[cur] > sz[son[fat]]) {
//                son[fat] = cur;
//            }
//        }
//       // for (int i = 1; i < n; i++) top[gpt[i]] = gpt[i] == son[fa[gpt[i]]] ? top[fa[gpt[i]]] : gpt[i];
//        p = 0;
//        stk[p++] = ort;
//        while(p>0) {
//            rt = stk[--p];
//            dfn[rt] = id;
//            pt[id++] = rt;
//            for (int i = h[rt]; i != -1; i = ne[i]) {
//                int v = to[i];
//                if (fa[rt] == v || v == son[rt]) continue;
//                top[v] = v;
//                stk[p++] = v;
//            }
//            if(son[rt]!=0) {
//                top[son[rt]] = top[rt];
//                stk[p++] = son[rt];
//            }
//        }
//
//
//    }


}

C++11(clang++ 3.9) 解法, 执行用时: 16ms, 内存消耗: 360K, 提交时间: 2020-05-30 10:21:14

#include<bits/stdc++.h>
using namespace std;
int N;
vector<int> G[512];
int dfn[512];
int low[512];
int clk;
int cut_cnt;
void dfs(int s,int f)
{
	dfn[s]=low[s]=++clk;
	int cnt=0;
	bool isCut=false;
	for(auto t:G[s])
	if(t!=f)
	{
		if(dfn[t])
		low[s]=min(low[s],dfn[t]);
		else
		{
			cnt++;
			dfs(t,s);
			low[s]=min(low[s],low[t]);
			if((f==-1&&cnt>1)||(f!=-1&&dfn[s]<=low[t]))
			isCut=true;
		}
	}
	if(isCut) cut_cnt++;
}
void init()
{
	for(int i=1;i<=N;i++)
	G[i].clear();
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	clk=cut_cnt=0;
}
int main()
{
	while(cin>>N&&N)
	{
		init();
		string s;
		getline(cin,s);
		while(getline(cin,s)&&s!="0")
		{
			stringstream ss(s);
			int u,v;
			ss>>u;
			while(ss>>v)
			G[u].push_back(v),G[v].push_back(u);
		}
		for(int i=1;i<=N;i++)
		if(!dfn[i])
		dfs(i,-1);
		cout<<cut_cnt<<endl;
	}
}

上一题