HDU 4496-D-市(互いに素セット)

D-市

時間制限:2000/1000 MS(Javaの/その他)メモリ制限:65535分の65535 K(Javaの/その他)
の合計提出(S):6470受理提出(S):2213

問題の説明

ルクサーは本当に悪い奴です。彼は、彼が出会ったすべてのものを破壊します。
ある日ルクサーは、D-市に行ってきました。D-cityがN D点及びM D-線を有します。各D-ラインは正確に2つのD点を結びます。ルクサーは、すべてのD-ラインを破壊します。D-市の市長は、D-街の多くの接続ブロックはルクサーは、入力の最初のK Dラインを破壊した後に残る方法を知りたいです。
それらは、直接または間接的に相互に接続した場合にのみ場合、2つの点が同一の接続ブロックです。

入力

入力の最初の行は2つの整数を含んでいるNとM.は
その後D-線である2スペースで区切られた整数uおよびvを含むM行それぞれを以下。
制約:
0 <N <= 10000
0 <M <= 100000
0 <= U、V <N.

出力

出力M線、i番目の行は、入力に最初のiのエッジを削除した後の答えです。

サンプル入力

5 10
0 1
1 2
1 3
1 4
0 2
2 3
0 4
0 3
3 4
2 4

サンプル出力

1
1
1
2
2
2
2
3
4
5

ヒント

サンプル入力で与えられたグラフは、頂点の各対は、それらを連結するエッジを有しているので、最初に1つだけ接続されたブロックがあること、完全グラフです。
グラフの最初の3つのエッジを削除した後、すべての頂点がまだ互いに接続ので、出力の最初の3行は1秒です。
しかし、グラフの最初の4辺を削除した後、頂点1は、他の頂点に切断され、それは独立した接続ブロックとなりました。
最後の出力は常にN.する必要がありますので、切断ブロックが増加したエッジを削除する続行し、最終的には、頂点の数になっただろう

問題の説明
ルークのSe(ルクサーは)本当に悪い人です。彼は、彼が出会ったすべてのものを破壊しました。
ある日、ルークSeがD-市に行ってきました。D-cityがN点及びM D D線を有しています。正確に2点を結ぶ各D D線。ルクソールは、すべてのD-ラインを破壊します。D-市長疑問後ルクサーはD-都市地域に接続残っているどのくらいの中のK Dライン入力の前に破壊しました。
そして2つのだけのポイント場合、直接または間接的に相互に接続されている場合、それらは、同じブロックに接続されています。

入力値
入力の最初の行のは、二つの整数N及びMを含有します
その後、各2スペースで区切られた整数uとvを含むM行は、Dは列を表します。
範囲:
0 <N <= 10000
0 <M <= 100000
0 <= U、V <N。

出力
出力M行、入力フロント側を消去した後、i行目のI応答。

サンプル入力
。5 10
0 1
1 2
。1. 3
。1 4
0 2
2 3
0 4
0 3
3 4
2 4

出力例
。1
1
1
2
2
2
2
。3
。4
。5

ヒント:
所与図サンプル入力は、各頂点の完全なビューが非常に一方のみ開始ブロックに接続され、それらを一緒に連結するエッジを有しています。
最初の三つの辺の削除グラフィック後、全ての頂点が一緒に残っているので、最初の三つの出力は、1に作用します。
しかし、前後のパターンの4辺が他の頂点、および独立した接続ブロックから切断頂点1を削除しました。
ブロックが切断された増加、エッジを削除し続け、それは頂点の最後の数となり、したがって常に最後の出力は、Nであるなければなりません

トピックリンク

タイトル効果:N都市与えられ、Nは現在の都市道路M(数字は必ずしも通信ではない)によって互いに接続されていることを意味し、M側を除去するために、次に、i番目のターンは、いくつかの解体を有する出力通信エリア。
あなたは、出力のm倍にしたいので、このタイトルは互いに素セットを調べ、過去とは異なり、我々は後方に保存することができるということです、始めて相互に接続されていない、と道アップからの最後の通信セット我々はそう:アイデアを問題解決配列のANSは、ANSは、私たちがしたいので、スタートは確かにお互い、その後も、裁判官に連通されていないので、父親は父親が同じノードである場合、異なるノード、ans-と通信することが可能であるならば、もう一度、でも逆方向に、例えばNを開始します最終的にはANSの出力値をオンにする、でも続けます。ACコード:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=1e5+50;
struct node {int a,b;};
int f[_max],s[_max];
node ai[_max];
int main()
{
	int n,m;
	int getf(int);
	while(~scanf("%d%d",&n,&m))
	{ 
	  int a,b,cnt=1;;
	  for(int i=1;i<=m;i++)
	    scanf("%d%d",&ai[i].a,&ai[i].b);
	  for(int i=0;i<n;i++)
	      f[i]=i;//初始化并查集
	  int sum=n;	  
	  for(int i=m;i>0;i--)
	  {
		s[i]=sum;
		int x=getf(ai[i].a);
		int y=getf(ai[i].b);
		if(x!=y)//判断父亲节点是否相同
		{
			sum--;
			f[y]=x;
		}
	  }
	  for(int i=1;i<=m;i++)
	    printf("%d\n",s[i]);
	}
	//system("pause");
	return 0;
}
int getf(int v)//寻找父亲节点
{
	if(f[v]==v)
	  return v;
	else
	{
		f[v]=getf(f[v]);
		return f[v];
	}  
}
公開された38元の記事 ウォンの賞賛1 ビュー1084

おすすめ

転載: blog.csdn.net/aezakmias/article/details/104877940