FloodFill
不说了….大家都会写…..
无向图割点Tarjan算法
主过程是一个DFS.
我们使用DFS对每个点记录两个值:
1.dfn[i] 表示点i是第几个DFS到的点.
2.low[i] 表示从点i出发,不经过DFS的点能绕回而取得的最小的dfn值.
那么当low[i]==dfn[i]时,i的子节点就只能从一条不是DFS中路径的路径回到自己,而不能回到i的父节点.
于是我们就可以断定i是一个割点.
dfn很好理解.
但是low怎么理解呢?
显然,我们的主要目的是找环.
假设我们DFS,经过了点i,到达点j.
那么DFS路径必定是一条点i到点j的路径.
我们想要找环,就一定不能从DFS路径走,而是要从别的地方走.
low一直取min就是为了使找到的环尽量大,使得它是极大环,只有这样的环才是一个严格的连通分量.
Code
#include <cstdio>
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstring>
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double db;
int getint()
{
int res=0; char c=getchar(); bool m=false;
while(c<'0' || c>'9') m=(c=='-'),c=getchar();
while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
return m ? -res : res;
}
const db eps=1e-18;
bool feq(db a,db b)
{ return fabs(b-a)<eps; }
using namespace std;
const int INF=(1<<30)-1;
struct edge
{
int in;
edge*nxt;
}pool[200000];
edge*et=pool;
edge*eds[1050];
inline edge*addedge(int i,int j)
{ et->in=j; et->nxt=eds[i]; eds[i]=et++; }
#define FOREACH_EDGE(i,j) for(edge*i=eds[j];i;i=i->nxt)
int n,m;
bool used[1050];
int dfn[1050];
int low[1050];
int cnt[1050];
int f[1050];
bool ins[1050];
int cur;
void DFS(int x)
{
used[x]=true;
low[x]=dfn[x]=cur++;
ins[x]=true;
FOREACH_EDGE(i,x)
{
if(!used[i->in])
{
DFS(i->in);
if(low[i->in]==dfn[x]) cnt[x]++;
low[x]=min(low[x],low[i->in]);
}else
{
if(i->in!=f[x])
low[x]=min(low[x],dfn[i->in]);
}
}
ins[x]=false;
}
void INIT()
{
et=pool;
memset(eds,0,sizeof(eds));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cnt,0,sizeof(cnt));
memset(f,0,sizeof(f));
memset(used,0,sizeof(used));
}
int main()
{
int a,b,T=1;
while(a=getint())
{
b=getint();
INIT();
addedge(a,b);
addedge(b,a);
while(a=getint())
{
b=getint();
addedge(a,b);
addedge(b,a);
}
cur=1;
f[1]=1;
DFS(1);
printf("Network #%d\n",T);
int tot=0;
if(cnt[1]>=2)
printf(" SPF node %d leaves %d subnets\n",1,cnt[1]),tot++;
for(int i=2;i<=1000;i++)
{
if(cnt[i]!=0)
{
printf(" SPF node %d leaves %d subnets\n",i,cnt[i]+1);
tot++;
}
}
if(!tot)
printf(" No SPF nodes\n");
printf("\n");
T++;
}
return 0;
}