zoukankan      html  css  js  c++  java
  • 【POJ3352】Road Construction(边双联通分量)

    题意:给一个无向图,问最少添加多少条边后能使整个图变成双连通分量。

    思路:双连通分量缩点,缩点后给度为1的分量两两之间连边,要连(ans+1) div 2条

             low[u]即为u所在的分量编号,flag=0,1,2表示没搜过,没搜完,搜完了

    POJ上pascal编译器出问题了不管怎么交都CE

    这次写的 应该能处理重边

     1 var head,vet,next,flag,dfn,low,fan,de:array[0..10000]of longint;
     2     n,m,i,e,v,ans,x,y,tot,time:longint;
     3 
     4 procedure add(a,b:longint);
     5 begin
     6  inc(tot);
     7  next[tot]:=head[a];
     8  vet[tot]:=b;
     9  head[a]:=tot;
    10 end;
    11 
    12 function min(x,y:longint):longint;
    13 begin
    14  if x<y then exit(x);
    15  exit(y);
    16 end;
    17 
    18 procedure dfs(u,le:longint);
    19 var e,v:longint;
    20 begin
    21  flag[u]:=1;
    22  inc(time); dfn[u]:=time; low[u]:=time;
    23  e:=head[u];
    24  while e<>0 do
    25  begin
    26   v:=vet[e];
    27   if e=fan[le] then
    28   begin
    29    e:=next[e];
    30    continue;
    31   end;
    32   if flag[v]=0 then
    33   begin
    34    dfs(v,e);
    35    low[u]:=min(low[u],low[v]);
    36   end
    37    else if flag[v]=1 then low[u]:=min(low[u],dfn[v]);
    38   e:=next[e];
    39  end;
    40  flag[u]:=2;
    41 end;
    42 
    43 begin
    44 
    45  for i:=0 to 2000 do
    46    if i mod 2=1 then fan[i]:=i+1
    47     else fan[i]:=i-1;
    48  while not eof do
    49  begin
    50   readln(n,m);
    51   if (n=0)and(m=0) then break;
    52   fillchar(head,sizeof(head),0);
    53   fillchar(low,sizeof(low),0);
    54   fillchar(de,sizeof(de),0);
    55   fillchar(flag,sizeof(flag),0);
    56   tot:=0; time:=0;
    57   for i:=1 to m do
    58   begin
    59    read(x,y);
    60    add(x,y);
    61    add(y,x);
    62   end;
    63   for i:=1 to n do
    64    if flag[i]=0 then dfs(i,0);
    65   for i:=1 to n do
    66   begin
    67    e:=head[i];
    68    while e<>0 do
    69    begin
    70     v:=vet[e];
    71     if low[v]<>low[i] then inc(de[low[i]]);
    72     e:=next[e];
    73    end;
    74   end;
    75   ans:=0;
    76   for i:=1 to n do
    77    if de[i]=1 then inc(ans);
    78   writeln((ans+1) div 2);
    79  end;
    80 
    81 end.

    这个是去年写的那时候AC了 好像不能处理重边

     1 var de,low,next,vet,head,flag,dfn:array[1..10000]of longint;
     2     n,m,tot,x,y,i,e,v,leaf,time:longint;
     3 
     4 function min(x,y:longint):longint;
     5 begin
     6  if x<y then exit(X);
     7  exit(y);
     8 end;
     9 
    10 procedure add(a,b:longint);
    11 begin
    12  inc(tot);
    13  next[tot]:=head[a];
    14  vet[tot]:=b;
    15  head[a]:=tot;
    16 end;
    17 
    18 procedure dfs(u,fa:longint);
    19 var e,v:longint;
    20 begin
    21  inc(time);
    22  dfn[u]:=time; low[u]:=time;
    23  flag[u]:=1;
    24  e:=head[u];
    25  while e<>0 do
    26  begin
    27   v:=vet[e];
    28   if v=fa then
    29   begin
    30    e:=next[e];
    31    continue;
    32   end;
    33   if flag[v]=0 then
    34   begin
    35    dfs(v,u);
    36    low[u]:=min(low[u],low[v]);
    37   end
    38    else if flag[v]=1 then low[u]:=min(low[u],dfn[v]);
    39   e:=next[e];
    40  end;
    41  flag[u]:=2;
    42 end;
    43 
    44 begin
    45 
    46  while not eof do
    47  begin
    48   readln(n,m);
    49   if (n=0)and(m=0) then break;
    50   fillchar(head,sizeof(head),0);
    51   tot:=0;
    52   for i:=1 to m do
    53   begin
    54    readln(x,y);
    55    add(x,y);
    56    add(y,x);
    57   end;
    58   fillchar(dfn,sizeof(dfn),0);
    59   fillchar(de,sizeof(de),0);
    60   fillchar(flag,sizeof(flag),0);
    61   time:=0;
    62   for i:=1 to n do
    63    if flag[i]=0 then dfs(i,i);
    64   for i:=1 to n do
    65   begin
    66    e:=head[i];
    67    while e<>0 do
    68    begin
    69     v:=vet[e];
    70     if low[i]<>low[v] then inc(de[low[i]]);
    71     e:=next[e];
    72    end;
    73   end;
    74   leaf:=0;
    75   for i:=1 to n do
    76    if de[i]=1 then inc(leaf);
    77   writeln((leaf+1) div 2);
    78  end;
    79 
    80 end.

     UPD(2018.10.18):C++

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second
     19 #define MP make_pair
     20 #define N   15000
     21 #define M   6100000
     22 #define eps 1e-8
     23 #define pi  acos(-1)
     24 #define oo  1e9
     25 
     26 int head[N],vet[N],nxt[N],flag[N],dfn[N],low[N],fan[N],d[N],
     27     tot,tim;
     28      
     29 void add(int a,int b)
     30 {
     31     nxt[++tot]=head[a];
     32     vet[tot]=b;
     33     head[a]=tot;
     34 }
     35 
     36 void dfs(int u,int le)
     37 {
     38     flag[u]=1;
     39     dfn[u]=low[u]=++tim;
     40     int e=head[u];
     41     while(e)
     42     {
     43         int v=vet[e];
     44         if(e==fan[le])
     45         {
     46             e=nxt[e];
     47             continue;
     48         }
     49         if(!flag[v])
     50         {
     51             dfs(v,e);
     52             low[u]=min(low[u],low[v]);
     53         }
     54          else if(flag[v]==1) low[u]=min(low[u],dfn[v]);
     55         e=nxt[e];
     56     }
     57     flag[u]=2;
     58 }
     59 
     60 int main()
     61 {
     62     freopen("poj3352.in","r",stdin);
     63     freopen("poj3352.out","w",stdout);
     64     for(int i=0;i<=2000;i++) 
     65      if(i&1) fan[i]=i+1;
     66       else fan[i]=i-1;
     67     int n,m;
     68     while(scanf("%d%d",&n,&m)!=EOF)
     69     {
     70         memset(head,0,sizeof(head));
     71         memset(low,0,sizeof(low));
     72         memset(d,0,sizeof(d));
     73         memset(flag,0,sizeof(flag));
     74         tot=tim=0;
     75         for(int i=1;i<=m;i++)
     76         {
     77             int x,y;
     78             scanf("%d%d",&x,&y);
     79             add(x,y);
     80             add(y,x);
     81         }
     82         for(int i=1;i<=n;i++)
     83          if(flag[i]==0) dfs(i,0);
     84         for(int i=1;i<=n;i++)
     85         {
     86             int e=head[i];
     87             while(e)
     88             {
     89                 int v=vet[e];
     90                 if(low[v]!=low[i]) d[low[i]]++;
     91                 e=nxt[e];
     92             }
     93         } 
     94         int ans=0;
     95         for(int i=1;i<=n;i++)
     96          if(d[i]==1) ans++;
     97         printf("%d
    ",(ans+1)/2); 
     98     }
     99     return 0;
    100 }
    101         
    102         
  • 相关阅读:
    【翻译自mos文章】 11gR1版本号 asmcmd的新命令--cp、md_backup、md_restore
    Android实现ListView或GridView首行/尾行距离屏幕边缘距离
    iOS-为方便项目开发在pch加入一些经常使用宏定义
    [ACM] FZU 1686 神龙的难题 (DLX 反复覆盖)
    Cocos2d-x Touch事件处理机制
    在linux環境下安裝jprofiler_linux_8_0_2.sh
    QT5 Failed to load platform plugin &quot;windows&quot; 终极解决方式 命令行问题
    我们想要如何子的生活?
    javaEE mvc样例具体解释
    安装Kali Linux操作系统Kali Linux无线网络渗透
  • 原文地址:https://www.cnblogs.com/myx12345/p/5910638.html
Copyright © 2011-2022 走看看