poj1144:

模板题吧,只是输入的方式真的真的非常非常的蛋疼,看了别人的博客才知道了怎么写○| ̄|_。记住这种写法!!!!!!

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define rep(i,n) for(int i=1;i<=n;i++)
 8 #define clr(x,c) memset(x,c,sizeof(x))
 9 const int nmax=105;
10 int dfn[nmax],low[nmax],iscut[nmax],n,dfn_clock;
11 vector<int>f[nmax];
12 int get(char *ch){
13     int x=0;
14     for(int i=0;ch[i];i++)
15       x=x*10+ch[i]-'0';
16     return x;
17 }
18 int dfs(int u,int fa){
19     low[u]=dfn[u]=++dfn_clock;
20     int child=0;
21     for(int i=0;i<f[u].size();i++){
22         int v=f[u][i];
23         if(!dfn[v]){
24             child++;
25             dfs(v,u);
26             low[u]=min(low[u],low[v]);
27             if(low[v]>=dfn[u])
28               iscut[u]=1;
29         }
30         else if(dfn[v]<dfn[u]&&v!=fa)
31           low[u]=min(low[u],dfn[v]);
32     }
33     if(fa<0&&child==1) iscut[u]=0;
34     return low[u];
35 
36 }
37 int main(){
38     while(scanf("%d",&n)&&n){
39         dfn_clock=0;
40         clr(dfn,0);clr(iscut,0);
41         rep(i,n) f[i].clear();
42         char ch[10];
43         while(scanf("%s",ch)==1){
44             if(ch[0]=='0') break;
45             int u=get(ch);
46             while(scanf("%s",ch)==1){
47                 int v=get(ch);
48                 f[u].push_back(v);
49                 f[v].push_back(u);
50                 char t=getchar();
51                 if(t=='\n') break;           //就是这里②| ̄|_
52             }
53         }
54         dfs(1,-1);
55         int ans=0;
56         rep(i,n)
57           if(iscut[i])
58             ans++;
59         printf("%d\n",ans);
60     }
61     return 0;
62 }

 poj2117:额没什么难度吧。只是求去掉一个割顶图能得到多少个连通分量。然后在判断的时候弄一下就好了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define rep(i,n) for(int i=1;i<=n;i++)
 8 #define clr(x,c) memset(x,c,sizeof(x))
 9 const int nmax=10005;
10 int dfn[nmax],low[nmax],cut[nmax],dfn_clock,n,m;
11 vector<int>f[nmax];
12 int read(){
13     int x=0;
14     char c=getchar();
15     while(!isdigit(c)) c=getchar();
16     while(isdigit(c)){
17         x=x*10+c-'0';
18         c=getchar();
19     }
20     return x;
21 }
22 void dfs(int u,int fa){
23     low[u]=dfn[u]=++dfn_clock;
24     for(int i=0;i<f[u].size();i++){
25         int v=f[u][i];
26         if(!dfn[v]){
27             dfs(v,u);
28             low[u]=min(low[u],low[v]);
29             if(low[v]>=dfn[u]){
30                 cut[u]++;
31             }
32         }
33         else if(dfn[v]<=dfn[u]&&v!=fa)
34           low[u]=min(low[u],dfn[v]);
35     }
36 }
37 int main(){
38     while(scanf("%d%d",&n,&m)==2&&n){
39         rep(i,n) f[i].clear();
40         rep(i,m){
41             int u=read(),v=read();
42             u++;
43             v++;
44             f[u].push_back(v);
45             f[v].push_back(u);
46         }
47         int ans=dfn_clock=0;
48         clr(dfn,0);clr(low,0);clr(cut,0);
49         rep(i,n){
50             if(!dfn[i]){
51                 ans++;
52                 dfs(i,-1);
53                 cut[i]--;
54             }
55         }
56         int tmp=-2;
57         rep(i,n)
58           tmp=max(tmp,cut[i]);
59         printf("%d\n",tmp+ans);
60     }
61     return 0;
62 }

 poj3352:

其实只要对边连通分量熟悉就好了,还有一个公式的应用就好了;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define rep(i,n) for(int i=1;i<=n;i++)
 8 #define clr(x,c) memset(x,c,sizeof(x))
 9 const int nmax=1005;
10 vector<int>f[nmax];
11 int out[nmax],dfn[nmax],low[nmax],n,m,dfn_clock=0;
12 void dfs(int x,int fa){
13     dfn[x]=low[x]=++dfn_clock;
14     for(int i=0;i<f[x].size();i++){
15         int v=f[x][i];
16         if(!dfn[v]){
17             dfs(v,x);
18             low[x]=min(low[x],low[v]);
19         }
20         else if(dfn[v]<dfn[x]&&v!=fa)
21           low[x]=min(low[x],dfn[v]);
22     }
23 }
24 int main(){
25     scanf("%d%d",&n,&m);
26     clr(dfn,0);clr(low,0);clr(out,0);
27     rep(i,m){
28         int u,v;
29         scanf("%d%d",&u,&v);
30         f[u].push_back(v);
31         f[v].push_back(u);
32     };
33     dfs(1,-1);
34     rep(i,n){
35         for(int j=0;j<f[i].size();j++){
36             int v=f[i][j];
37             if(low[i]!=low[v])
38               out[low[v]]++;
39         }
40     }
41     int ans=0;
42     rep(i,n){
43         if(out[i]==1)
44           ans++;
45     }
46     printf("%d\n",(ans+1)/2);
47     return 0;
48 
49 }

 poj3177:

又是道水题,不过重边判断只能那样低效判断吗○| ̄|_不知道有没有高效一点的方法;果然邻接表跑的比vector好多了;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 #define rep(i,n) for(int i=1;i<=n;i++)
 7 #define clr(x,c) memset(x,c,sizeof(x))
 8 struct edge{
 9     int to,next;
10 }; 
11 edge e[20005];
12 int dfn[5004],low[5005],out[5005],h[5005],n,m,dfn_clock=0,map[5005][5005];
13 int read(){
14     int x=0;
15     char c=getchar();
16     while(!isdigit(c)) c=getchar();
17     while(isdigit(c)) {
18         x=x*10+c-'0';
19         c=getchar();
20     }
21     return x;
22 }
23 void dfs(int u,int fa){
24     dfn[u]=low[u]=++dfn_clock;
25     for(int i=h[u];i;i=e[i].next){
26         int v=e[i].to;
27         if(!dfn[v]){
28             dfs(v,u);
29             low[u]=min(low[u],low[v]);
30         }
31         else if(dfn[v]<dfn[u]&&v!=fa){
32             low[u]=min(low[u],dfn[v]);
33         }
34     }
35 }
36 int main(){
37     n=read();m=read();
38     int cur=0;
39     rep(i,m){
40         int u=read(),v=read();
41         map[u][v]=map[v][u]=1;
42     }
43     rep(i,n)
44       rep(j,n)
45         if(map[i][j]){
46             e[++cur].to=j;
47             e[cur].next=h[i];
48             h[i]=cur;
49         }
50     dfs(1,-1);
51     rep(i,n){
52         for(int j=h[i];j;j=e[j].next){
53             int tmp=e[j].to;
54             if(low[i]!=low[tmp]){
55                 out[low[tmp]]++;
56             }
57         }
58     }
59     int ans=0;
60     rep(i,n)
61       if(out[i]==1)
62         ans++;
63     printf("%d\n",(ans+1)/2);
64     return 0;
65 }