• ZOJ2588(BuringBridges)


    题目链接

     求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序)。

    由于有重边,一般需要使用邻接表来存储,我一开始嫌麻烦,想使用邻接矩阵和边集来存,没注意到节点数目太大,结果MLE。最终还是得用邻接表,写好后,有贡献了一次PE,改正格式后居然WA了,经检查在插入边时有点问题,插入时要先查找该边是否已出现,当初使用的是if(findEdge(a,b)==0&&findEdge(b,a)==0)来判断边是否已插入,后来发现这个不能保证findEdge(a,b)和findEdge(b,a)都会执行,改成if(findEdge(a,b)+findEdge(a,b))就AC了。但至今不解当初为何会PE,OJ是按怎样的顺序判错的呢?

    View Code
      1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <memory.h>
    4 #define MIN(a,b) ((a)<(b)?(a):(b))
    5 #define N 10001
    6 struct node
    7 {
    8 int v,id,cnt;
    9 struct node *next;
    10 };
    11 struct node *list[N];
    12 char vis[N];
    13 int dfn[N],low[N],father[N],n,m,id,ans[N],num;
    14 int findEdge(int u,int v)
    15 {
    16 struct node *p=list[u];
    17 while(p)
    18 {
    19 if(p->v==v)
    20 {
    21 p->cnt++;
    22 return 1;
    23 }
    24 p=p->next;
    25 }
    26 return 0;
    27 }
    28 void addEdge(int u,int v,int id)
    29 {
    30 struct node *p=(struct node*)malloc(sizeof(struct node));
    31 p->id=id;
    32 p->v=v;
    33 p->next=0;
    34 p->cnt=1;
    35 if(list[u])
    36 {
    37 p->next=list[u];
    38 list[u]=p;
    39 }
    40 else list[u]=p;
    41 }
    42 void init()
    43 {
    44 memset(vis,0,sizeof(vis));
    45 memset(father,0,sizeof(father));
    46 dfn[1]=low[1]=id=1;
    47 vis[1]=1;
    48 num=0;
    49 }
    50 void dfs(int u)
    51 {
    52 int v;
    53 struct node *p=list[u];
    54 while(p)
    55 {
    56 v=p->v;
    57 if(father[u]!=v)
    58 {
    59 if(vis[v]) low[u]=MIN(low[u],dfn[v]);
    60 else
    61 {
    62 father[v]=u;
    63 vis[v]=1;
    64 id++;
    65 dfn[v]=low[v]=id;
    66 dfs(v);
    67 low[u]=MIN(low[v],low[u]);
    68 if(dfn[u]<low[v]&&p->cnt==1)
    69 {
    70 ans[num++]=p->id;
    71 }
    72 }
    73 }
    74 p=p->next;
    75 }
    76 }
    77 int cmp(const void *a,const void *b)
    78 {
    79 return *(int *)a-*(int *)b;
    80 }
    81 int main()
    82 {
    83 int i,t,a,b,f;
    84 struct node *p;
    85 freopen("in.txt","r",stdin);
    86 scanf("%d",&t);
    87 while(t--)
    88 {
    89 scanf("%d%d",&n,&m);
    90 for(i=1; i<=m; i++)
    91 {
    92 scanf("%d%d",&a,&b);
    93 f=findEdge(a,b)+findEdge(b,a);
    94 if(!f)
    95 {
    96 addEdge(a,b,i);
    97 addEdge(b,a,i);
    98 }
    99 }
    100 init();
    101 dfs(1);
    102 qsort(ans,num,sizeof(ans[0]),cmp);
    103 printf("%d\n",num);
    104 if(num)
    105 {
    106 printf("%d",ans[0]);
    107 for(i=1; i<num; i++) printf(" %d",ans[i]);
    108 printf("\n");
    109 }
    110 if(t) printf("\n");
    111 for(i=1; i<=n; i++)
    112 {
    113 p=list[i];
    114 while(p)
    115 {
    116 list[i]=p->next;
    117 free(p);
    118 p=list[i];
    119 }
    120 }
    121 }
    122 return 0;
    123 }
  • 相关阅读:
    POJ 3630 Phone List | Trie 树
    POJ 3974 Palindrome | 马拉车模板
    POJ 3422 Kaka's Matrix Travels | 最小费用最大流
    POJ 2195 Going Home | 带权二分图匹配
    POJ 3068 "Shortest" pair of paths | 最小费用最大流
    POJ 3686 The Windy's | 最小费用最大流
    洛谷 最小费用最大流 模板 P3381
    POJ 2987 Firing | 最大权闭合团
    POJ 3469 Dual Core CPU | 最小割
    POJ 3281 Dining | 最大流
  • 原文地址:https://www.cnblogs.com/algorithms/p/2425544.html
Copyright © 2020-2023  润新知