HDU 4738 Caocao's Bridges(ブリッジ、エッジが重いためフォワードスターを使用するため、ビット操作はすべてブラケットする必要があります)
カオビオはチビの戦いで諸葛亮と周遊に敗れた。しかし、彼はあきらめませんでした。Caocaoの軍隊はまだ水の戦いが苦手だったので、彼は別のアイデアを思いつきました。彼は長江に多くの島を建設しました、そしてそれらの島に基づいて、Caocaoの軍は周遊の軍隊を簡単に攻撃することができました。Caocaoはまた、島をつなぐ橋を建てました。すべての島が橋で結ばれている場合、カカオの軍隊はそれらの島の間で非常に便利に配備できました。周遊はそれに耐えられなかったので、彼はいくつかのカカオの橋を破壊して、1つ以上の島を他の島から分離したいと考えました。しかし、周遊は諸葛亮が残した爆弾を1つしか持っていなかったため、橋を1つだけ破壊することができました。周優は、橋を破壊するために爆弾を運ぶ誰かを送り出さなければなりません。橋の上に警備員がいるかもしれません。爆撃チームの兵士の数は橋の警備員の数より少なくなることはできません、さもなければ任務は失敗します。島離島任務を完了するために周遊が何人の兵士を派遣しなければならないか、少なくとも理解してください。
入力
12を超えるテストケースはありません。
各テストケース:
最初の行には、NとMの2つの整数が含まれています。これは、N個のアイランドとM個のブリッジがあることを意味します。すべての島には1からNまでの番号が付けられています。(2 <= N <= 1000、0 <M <= N2)
次のM行は、Mブリッジを示しています。各ラインには3つの整数U、V、Wが含まれています。つまり、アイランドUとアイランドVを接続するブリッジがあり、そのブリッジにはWガードがあります。(U≠Vおよび0 <= W <= 10,000)
入力はN = 0およびM = 0で終了します。
出力
各テストケースについて、ミッションを完了するために周遊が送信しなければならなかった最小の兵士番号を印刷します。Zhou Yuがどうしても成功しなかった場合は、代わりに-1を出力します。
質問:Cao Caoには無向グラフがあり、画像にいくつかのエッジがあります。ZhouYuは、Cao Caoの無向グラフが複数の部分に分割されるように、1人のエッジを爆破するように何人かの人々に送信したいと考えています。CaoCaoの各エッジにはガードがあります。ZhouYuが送信されました人の数は側の警備員の数より少なくすることはできません。少なくとも何人を送るべきか尋ねてください。
- ヘビーサイド加工に注意し、チェーンフォワードスターを使用。
- ガードが0の場合は、人を送る必要もあります。
- 元の画像が接続されていない場合(tarjanが複数回)、誰かを送信する必要はありません。答えは0です。
- 答えは、すべてのブリッジの中で最小のエッジウェイトを直接出力します。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;
int n, m;
int bridge[N];
int dfn[N], low[N], num;
int head[N], ver[M], nex[M], edge[M], tot;
int ans;
int dcc_cnt;
int min_bridge;
void init()
{
num = tot = dcc_cnt = 0;
memset(head, -1, sizeof head);
memset(dfn, 0, sizeof dfn);
memset(low, 0, sizeof low);
min_bridge = INF;
}
void add(int x, int y, int z)
{
ver[tot] = y;
edge[tot] = z;
nex[tot] = head[x];
head[x] = tot ++ ;
}
void tarjan(int x, int in_edge)
{
dfn[x] = low[x] = ++ num;
for(int i = head[x] ;~i; i = nex[i]){
int y = ver[i], z = edge[i];
if(!dfn[y]){
tarjan(y, i);
low[x] = min(low[x], low[y]);
if(dfn[x] < low[y]){
bridge[i] = bridge[i ^ 1] = true;
min_bridge = min(min_bridge, z);
}
}
else if(i != (in_edge ^ 1))
low[x] = min(low[x], dfn[y]);
}
}
int main()
{
while(~scanf("%d%d", &n, &m) && n ){
init();
for(int i = 1; i <= m; ++ i){
int x, y ,z;
scanf("%d%d%d", &x, &y, &z);
add(x, y, z), add(y, x, z);
}
dcc_cnt = 0;
for(int i = 1; i <= n; ++ i)
if(!dfn[i])
tarjan(i, 0), dcc_cnt ++ ;
if(dcc_cnt > 1){
//tarjan多次说明不连通,直接输出0
printf("0\n");
continue;
}
if(min_bridge == INF)min_bridge = -1;
else if(min_bridge == 0)min_bridge = 1;
printf("%d\n", min_bridge);
}
return 0;
}