题目传送门:【POJ 1144】
题目大意:有 n 个点(1 ≤ n ≤ 100),每个点之间都有相连的边。问图中有多少不同的割点。
题目分析:
模板题。直接用 Tarjan算法求割点即可。
具体操作:
void tarjan(int u,int fa) //fa 表示父节点
这道题输入很奇怪啊……真的是读不懂……
下面附上代码:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<stack>
- using namespace std;
- typedef long long LL;
- const int MX=105;
- const int INF=0x3f3f3f3f;
- struct Edge{
- int to,len,next;
- }edge[MX*MX];
- int n,head[MX],now=0;
- int dfn[MX],low[MX],cnt[MX],_index=0,tot=0;
- bool iscut[MX];
- inline void adde(int u,int v){
- edge[++now].to=v;
- edge[now].next=head[u];
- head[u]=now;
- }
- void tarjan(int u,int fa){ //fa 是编号
- ++_index;
- low[u]=dfn[u]=_index;
- int child=0; //表示 u 有多少个孩子(子树)
- for (int i=head[u];i;i=edge[i].next){
- int v=edge[i].to;
- if (v==fa) continue;
- if (!dfn[v]){
- child++;
- tarjan(v,u);
- if (low[v]<low[u]){
- low[u]=low[v];
- }
- if (low[v]>=dfn[u]){
- iscut[u]=true;
- }
- } else if (dfn[v]<low[u]){
- low[u]=dfn[v];
- }
- }
- if (u==1 && child==1) iscut[u]=false;
- }
- void _init(){
- memset(head,0,sizeof(head));
- memset(dfn,0,sizeof(dfn));
- memset(iscut,0,sizeof(iscut));
- now=0,_index=0,tot=0;
- }
- int main(){
- while(scanf(“%d”,&n) && n) { //输入是粘的板子。。。
- _init();
- int x,y;
- while(scanf(“%d”,&x) && x) {
- while(getchar()!=‘\n’) {
- scanf(”%d”,&y);
- adde(x,y);
- adde(y,x);
- }
- }
- tarjan(1,-1);
- for (int i=1;i<=n;i++){
- if (iscut[i]) tot++;
- }
- printf(”%d\n”,tot);
- }
- return 0;
- }