神坑题。这题的坑点有1.判断连通,2.有重边,3.至少要有一个人背炸药
因为有重边,tarjan的时候不能用子结点和父节点来判断是不是树边的二次访问,所以我的采用用前向星存边编号的奇偶性关系,用^1来判断是不是树边
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxe = 1000005<<1;
const int maxv = 1005;
int clock;
int dfn[maxv],low[maxv],ecnt;
int head[maxv],nxt[maxe],to[maxe],wei[maxe];
void init()
{
clock = ecnt = 0;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
}
void addEdge(int u,int v,int w)
{
to[ecnt] = v;
wei[ecnt] = w;
nxt[ecnt] = head[u];
head[u] = ecnt++;
}
int ans;
void tarjan(int u,int fa)
{
dfn[u] = low[u] = ++clock;
for(int i = head[u]; ~i ; i = nxt[i]){
int v = to[i];
if(i == (fa^1)) continue;
if(!dfn[v]){
tarjan(v,i);
low[u] = min(low[u],low[v]);
if(low[v] > dfn[u]){
ans = min(ans,wei[i]);
}
}else {
low[u] = min(low[u],dfn[v]);
}
}
}
int sum;
bool vis[maxv];
void dfs(int u){
if(vis[u]) return;
sum++;
vis[u] = 1;
for(int i = head[u]; ~i ; i = nxt[i]){
dfs(to[i]);
}
}
const int INF = 1e9;
int main()
{
int N,M;
while(~scanf("%d%d",&N,&M)&&N){