1、 傳話
(message.pas/c/cpp)
【問題描述】
興趣小組的同學來自各個學校,為了增加友誼,晚會上又進行了乙個傳話的遊戲,如果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 61 2
2 34 1
3 11 3
2 3【輸出樣例】tt
tf其實這道題標程就只用了乙個dfs,對每乙個點搜一次,看能不能搜到起點,o(n^2)的演算法也能過。
我用了個tarjan,如果所屬的強連通分量度大於1,說明有環,o(n)。
比較固定,還是很簡單的。
#include #include using std::min;
struct node
;node* head[1010];
long getint()
do rs=(rs<<1)+(rs<<3)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}void insert(long a,long b)
long time = 0;
long bcnt = 0;
long belong[1010];
long dfn[1010];
long low[1010];
bool instack[1010];
long stack[1010];
bool hash[1010][1010];
long cnt[1010];
long top = 0;
void tarjan(long u)
else if (instack[v])
}if (dfn[u] == low[u])
while (u != v); }}
int main()
return 0;
}
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...
強連通分量
對於有向圖的乙個頂點集,如果從這個頂點集的任何一點出發都可以到達該頂點集的其餘各個頂點,那麼該頂點集稱為該有向圖的乙個強連通分量。有向連通圖的全部頂點組成乙個強連通分量。我們可以利用tarjan演算法求強連通分量。define n 1000 struct edge e 100000 int ec,p...
強連通分量
在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 下圖中,子圖為乙個強連通分量,因為...