1. 程式人生 > >【幾道題】Tarjan練習

【幾道題】Tarjan練習

【COGS8】 備用交換機

【問題描述】
n個城市之間有通訊網路,每個城市都有通訊交換機,直接或間接與其它城市連線。因電子裝置容易損壞,需給通訊點配備備用交換機。但備用交換機數量有限,不能全部配備,只能給部分重要城市配置。於是規定:如果某個城市由於交換機損壞,不僅本城市通訊中斷,還造成其它城市通訊中斷,則配備備用交換機。請你根據城市線路情況,計算需配備備用交換機的城市個數,及需配備備用交換機城市的編號。
【輸入格式】
輸入檔案有若干行
第一行,一個整數n,表示共有n個城市(2<=n<=100)
下面有若干行,每行2個數a、b,a、b是城市編號,表示a與b之間有直接通訊線路。
【輸出格式】
輸出檔案有若干行
第一行,1個整數m,表示需m個備用交換機,下面有m行,每行有一個整數,表示需配備交換機的城市編號,輸出順序按編號由小到大。如果沒有城市需配備備用交換機則輸出0。
【輸入輸出樣例】
輸入檔名: gd.in

7
1 2
2 3
2 4
3 4
4 5
4 6
4 7
5 6
6 7

輸出檔名:gd.out

2
2
4

求割點

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct edge
{
    int v, next;
}map[10001];

int n, a, b, root, cnt=0, dep=0, ans=0;
int head[101
], low[101], dfn[101]; bool point[101]; void add(int x, int y) { map[++cnt].v = y; map[cnt].next = head[x]; head[x] = cnt; } void tarjan(int x) { int son = 0; low[x] = dfn[x] = ++dep; for(int i=head[x]; i!=0; i=map[i].next) { if(dfn[map[i].v]==0) { tarjan(map
[i].v); son++; low[x] = min(low[x], low[map[i].v]); if((x==root && son>1) || (x!=root && low[map[i].v]>=dfn[x])) if(!point[x]) point[x] = true, ans++; } else low[x] = min(low[x], dfn[map[i].v]); } } int main() { freopen("gd.in", "r", stdin); freopen("gd.out", "w", stdout); scanf("%d", &n); while(scanf("%d%d", &a, &b)!=EOF) {add(a, b);add(b, a);} for(int i=1; i<=n; i++) if(dfn[i]==0) {root=i; tarjan(i);} printf("%d\n", ans); for(int i=1; i<=n; i++) { if(point[i]) printf("%d\n", i); } return 0; }

【COGS 618】 傳話

[問題描述]
興趣小組的同學來自各個學校,為了增加友誼,晚會上又進行了一個傳話遊戲,如果 a 認識 b ,那麼 a 收到某個訊息,就會把這個訊息傳給 b ,以及所有 a 認識的人。
如果 a 認識 b , b 不一定認識 a 。
所有人從 1 到 n 編號,給出所有“認識”關係,問如果 i 釋出一條新訊息,那麼會不會經過若干次傳話後,這個訊息傳回給了 i , 1<=i<=n 。
[輸入檔案]
輸入檔案 message.in 中的第一行是兩個數 n(n<1000) 和 m(m<10000) ,兩數之間有一個空格,表示人數和認識關係數。
接下來的 m 行,每行兩個數 a 和 b ,表示 a 認識 b 。 1<=a, b<=n 。認識關係可能會重複給出,但一行的兩個數不會相同。
[輸出檔案]
輸出檔案 message.out 中一共有 n 行,每行一個字元 T 或 F 。第 i 行如果是 T ,表示 i 發出一條新訊息會傳回給 i ;如果是 F ,表示 i 發出一條新訊息不會傳回給 i 。
[輸入樣例]
4 6
1 2
2 3
4 1
3 1
1 3
2 3
[輸出樣例]
T
T
T
F

找強連通分量

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct edge
{
    int v, next;
}e[200001];

int u, v, t=0, colnum=0;
int n, m, p=0, cnt=0, dep=0;
int head[100001], dfn[100001], low[100001], sta[100001];
int sum[100001], color[100001];
bool insta[100001];

void add(int x, int y)
{
    e[++cnt].next = head[x];
    e[cnt].v = y;
    head[x] = cnt;
}

void tarjan(int x)
{
    dfn[x] = low[x] = ++dep;
    sta[++p] = x; insta[x]= true;
    for(int i=head[x]; i!=0; i=e[i].next)
    {
        if(dfn[e[i].v]==0)
        {
            tarjan(e[i].v);
            low[x] = min(low[x], low[e[i].v]);
        }
        else if(insta[e[i].v]) low[x] = min(low[x], dfn[e[i].v]);
    }

    if(dfn[x]==low[x])
    {
        colnum++;
        do
        {
            color[sta[p]] = colnum;
            sum[colnum]++;
            insta[sta[p]] = false;
        }
        while(sta[p--]!=x);
    }
}

int main()
{
    freopen("messagew.in", "r", stdin);
    freopen("messagew.out", "w", stdout);

    scanf("%d%d", &n, &m);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d", &u, &v);
        add(u, v);// add(v, u);
    }

    for(int i=1; i<=n; i++) if(dfn[i]==0) tarjan(i);
    for(int i=1; i<=n; i++) 
    {
        if(sum[color[i]]>1) printf("T\n");
        else printf("F\n");
    }

    return 0;
}

【COGS 921】 [東方S1] 上白澤慧音

題目描述
在幻想鄉,上白澤慧音是以知識淵博聞名的老師。春雪異變導致人間之裡的很多道路都被大雪堵塞,使有的學生不能順利地到達慧音所在的村莊。因此慧音決定換一個能夠聚集最多人數的村莊作為新的教學地點。人間之裡由N個村莊(編號為1..N)和M條道路組成,道路分為兩種一種為單向通行的,一種為雙向通行的,分別用1和2來標記。如果存在由村莊A到達村莊B的通路,那麼我們認為可以從村莊A到達村莊B,記為(A,B)。當(A,B)和(B,A)同時滿足時,我們認為A,B是絕對連通的,記為。絕對連通區域是指一個村莊的集合,在這個集合中任意兩個村莊X,Y都滿足。現在你的任務是,找出最大的絕對連通區域,並將這個絕對連通區域的村莊按編號依次輸出。若存在兩個最大的,輸出字典序最小的,比如當存在1,3,4和2,5,6這兩個最大連通區域時,輸出的是1,3,4。
輸入格式
第1行:兩個正整數N,M
第2..M+1行:每行三個正整數a,b,t, t = 1表示存在從村莊a到b的單向道路,t = 2表示村莊a,b之間存在雙向通行的道路。保證每條道路只出現一次。
輸出格式
第1行: 1個整數,表示最大的絕對連通區域包含的村莊個數。
第2行:若干個整數,依次輸出最大的絕對連通區域所包含的村莊編號。
輸入樣例
5 5
1 2 1
1 3 2
2 4 2
5 1 2
3 5 1
輸出樣例
3
1 3 5
資料範圍
對於60%的資料:N <= 200且M <= 10,000
對於100%的資料:N <= 5,000且M <= 50,000

強連通分量

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 5001
#define MAXM 50001

int n, m, x, y, t;
int p=0, cnt=0, dep=0, colornum=0;
int dfn[MAXN], low[MAXN], sum[MAXN];
int head[MAXN], stack[MAXN], color[MAXN];
bool instack[MAXN];

struct edge
{
    int v, pre;
}e[MAXM];

void add(int u, int v)
{
    e[++cnt].v = v;
    e[cnt].pre = head[u];
    head[u] = cnt;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++dep;
    stack[++p] = u; instack[u] = true;
    for(int i=head[u]; i!=0; i=e[i].pre)
    {
        int v = e[i].v;
        if(dfn[v]==0)
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(instack[v]) low[u] = min(low[u], dfn[v]);
    }

    if(low[u]==dfn[u])
    {
        colornum++;
        do
        {
            color[stack[p]] = colornum;
            sum[colornum]++;
            instack[stack[p]] = false;
        }
        while(u!=stack[p--]);
    }
}

int main()
{
    freopen("classroom.in", "r", stdin);
    freopen("classroom.out", "w", stdout);

    scanf("%d%d", &n, &m);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d%d", &x, &y, &t);
        add(x, y); if(t==2) add(y, x);
    }
    for(int i=1; i<=n; i++) if(dfn[i]==0) tarjan(i);

    int maxs = 0, outcol = 0;
    for(int i=1; i<=n; i++)
    {
        if(sum[color[i]]>maxs)
        {
            outcol = color[i];
            maxs = sum[color[i]];
        }
    }

    printf("%d\n", maxs);
    for(int i=1; i<=n; i++) if(color[i]==outcol) printf("%d ", i);

    return 0;
}

相關推薦

Tarjan練習

【COGS8】 備用交換機 【問題描述】 n個城市之間有通訊網路,每個城市都有通訊交換機,直接或間接與其它城市連線。因電子裝置容易損壞,需給通訊點配備備用交換機。但備用交換機數量有限,不能全部配備,只能給部分重要城市配置。於是規定:如果某個城市由於交

不吹不擂,你想要的Python面試都在這裏了315+

def 每天 leet soup XML unique 通信 cors 後進先出 https://www.cnblogs.com/wupeiqi/p/9078770.html 近日恰逢學生畢業季,課程後期大家“期待+苦逼”的時刻莫過於每天早上內容回顧和面試題問答部分【臨

Python面試315

第一部分 Python基礎篇(80題) 1、為什麼學習Python? 2、通過什麼途徑學習的Python? 3、Python和Java、PHP、C、C#、C++等其他語言的對比? 4、簡述解釋型和編譯型程式語言? 5、Python直譯器種類以及特點?

你想要的Python面試都在這裡了315+

第一部分 Python基礎篇(80題)1、為什麼學習Python?2、通過什麼途徑學習的Python?3、Python和Java、PHP、C、C#、C++等其他語言的對比?4、簡述解釋型和編譯型程式語言

Ubuntu14 server + Hadoop2.2.0環境下Sqoop1.99.3部署記錄

tool share 環境變量 解壓 gdi yar base soft mil 第一步。下載、解壓、配置環境變量: 官網下載sqoop1.99.3 http://mirrors.cnnic.cn/apache/sqoop/1.99.3/ 將sqoop解

文件修改_練習

ges 分享 pytho lines round readlines odi with image 文件1: 文件2: 要求:把文件1裏第一行內容"11111111111"改成"888888888"然後把整個文件的內容寫到文件2裏去,最後把文件2的名字改成文件1的名字;

基礎水統計單詞個數

int pan 一個 else art 個數 print urn 是不是 1 //1.統計單詞的個數 2 #include <stdio.h> 3 int main(void) 4 { 5 int i, flag = 0, number =

LeetCode刷SQL-Combine Two Tables

介紹 左關聯查詢 col 每一個 cit http sid combine sql查詢 Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ |

練習賽補poj 3026 Borg Maze bfs+最小生成樹坑~

lec pro 起點 live tin put gets work cond Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant

編程下廚房

main 下廚房 包含 ins size out 測試 text 表示 【編程題】下廚房 題目描述   牛牛想嘗試一些新的料理,每個料理需要一些不同的材料,問完成所有的料理需要準備多少種不同的材料。 輸入描述:   每個輸入包含 1 個測試用例。每個測試用例的第 i 行,表

2017 ACM-ICPC 亞洲區(西安賽區)網絡賽C. Sum腦洞

整數 namespace pac line main expr esp for cnblogs 限制:1000ms 32768K Define the function S(x) for xx is a positive integer. S(x) equals to t

BZOJ3629-聰明的燕姿數學雜

cee left weibo sina iuc info ndt www. style T浪h改姆9少FVT優樂Phttp://www.docin.com/vwhd00606 AM0瓤XN7Ukahttp://weibo.com/u/6367436044 蹈4s釉畏耐E

編程不引入第三個變量,而交換兩個變量的值

其中 blog b+ 沒有 來源 article else 位移 text 不引入第三個變量,而交換兩個變量的值 方法一:算術運算 1 int a,b; 2 a=10;b=12; 3 a=b-a; //a=2;b=12 4 b=b-a; //a=2;b=10

C語言之非常簡單的

語言 scanf void 類型 比較 簡單 bsp 增長 語句   C語言之非常簡單的幾道題(還是寫寫),比較簡單吧,主要有幾道題的數據類型(如,第三題)和語句順序(如,第二題)需要註意一小下下。 1. 求表達式S=1*2*3……*N的值大於150時,最小的N的值

大家可以看看這你們會嗎??

變量 答案 .html clu 網址 ptr 編譯 是什麽 編譯器 以下程序的結果是什麽? int i = 1;int main(){int i = i;return 0;}A: main()函數裏的i是一個未定義值 B: main()函數的i為1 C: 編譯器不允許這種寫

劍指offer——python第4重建二叉樹

代碼 subject 序列 eno 描述 color index urn describe 題目描述 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重復的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中

劍指offer——python第38二叉樹的深度

描述 sub pan 節點 solution class oot 返回值 self. 題目描述 輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。 解題思路 想了很久。。首先本渣渣就不太理解遞歸在pyt

BZOJ1718: [Usaco2006 Jan] Redundant Paths 分離的路徑邊雙模板傻逼

LINK 經典傻逼套路 就是把所有邊雙縮點之後葉子節點的個數 //Author: dream_maker #include<bits/stdc++.h> using namespace std; //------------------------------------------

LeetCode 簡單64-二叉搜尋樹的最近公共祖先

宣告: 今天是第64道題。給定一個二叉搜尋樹, 找到該樹中兩個指定節點的最近公共祖先。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除 (手動比心ღ( ´・ᴗ・` )) 正文 題目:

LeetCode 簡單63-迴文連結串列

宣告: 今天是第63道題。請判斷一個連結串列是否為迴文連結串列。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除 (手動比心ღ( ´・ᴗ・` )) 正文 題目:請判斷一個連結串列是否