hdu 4612 Warm up(缩点+树上最长链)
本来就是自己负责图论,结果水了= =
题目其实很裸,就是求桥的数量,只是要新加上一条边罢了。做法:先缩点、再在树上搜最长链(第一场多校的hdu 4607 Park Visit就考了最长链,小样,套个马甲以为就认不出你了),加边后求桥数就可以了。
犯了一大三小四个错误-_-
竟然真的去套模板求桥数了。。竟然没注意到树边都是桥,用树边减链边就可以了。
然后,重新建图的Build()把n传进去了。
再然后,发现读数据从0~m-1,Build()里竟然是1~m。
再再然后,原来存边的su[],sv[]数组开成了 MAXN。
1 #pragma comment(linker, "/STACK:10240000000000,10240000000000") 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 using namespace std; 7 8 const int MAXM=1111111; 9 const int MAXN=222222; 10 11 struct Edge{ 12 int u,v,next; 13 int vis; 14 Edge(){} 15 Edge(int _u,int _v,int _next):u(_u),v(_v),next(_next),vis(0){} 16 }edge[MAXM<<1]; 17 18 int brige[MAXM<<1]; 19 20 struct Q{ 21 int p,c; 22 }q[MAXN]; 23 24 int head[MAXN],tol; 25 int stk[MAXN],top; 26 int low[MAXN],dfn[MAXN],TT; 27 int belong[MAXN],scc; 28 29 int vis[MAXN]; 30 31 int su[MAXM],sv[MAXM]; 32 33 int son; 34 35 void init() 36 { 37 tol=0; 38 memset(head,-1,sizeof(head)); 39 } 40 41 void add(int u,int v) 42 { 43 edge[tol]=Edge(u,v,head[u]); 44 head[u]=tol++; 45 } 46 47 void tarjan(int u) 48 { 49 int v; 50 stk[++top]=u; 51 low[u]=dfn[u]=++TT; 52 for(int i=head[u];i!=-1;i=edge[i].next) 53 { 54 if(edge[i].vis) 55 continue; 56 edge[i].vis=edge[i^1].vis=1; 57 58 v=edge[i].v; 59 if(!dfn[v]){ 60 tarjan(v); 61 low[u]=min(low[u],low[v]); 62 }else { 63 low[u]=min(low[u],dfn[v]); 64 } 65 } 66 if(dfn[u]==low[u]){ 67 scc++; 68 do{ 69 v=stk[top--]; 70 //ins[v]=0; 71 belong[v]=scc; 72 }while(v!=u); 73 } 74 } 75 76 void Build(int m) 77 { 78 init(); 79 for(int i=0;i<m;i++) 80 { 81 int u=su[i],v=sv[i]; 82 if(belong[u]!=belong[v]){ 83 add(belong[u],belong[v]); 84 add(belong[v],belong[u]); 85 } 86 } 87 } 88 89 int bfs(int x) 90 { 91 int l,r,u; 92 93 l=r=0; 94 q[r].p=x; 95 q[r++].c=1; 96 memset(vis,0,sizeof(vis)); 97 vis[x]++; 98 while(l<r) 99 { 100 u=q[l].p; 101 int c=q[l++].c; 102 for(int i=head[u];i!=-1;i=edge[i].next) 103 { 104 int v=edge[i].v; 105 if(!vis[v]){ 106 q[r].p=v; 107 q[r++].c=c+1; 108 vis[v]=1; 109 } 110 } 111 } 112 return u; 113 } 114 115 int main() 116 { 117 int n,m; 118 while(~scanf("%d%d",&n,&m)) 119 { 120 if(!n&&!m) 121 return 0; 122 init(); 123 for(int i=0;i<m;i++) 124 { 125 scanf("%d%d",&su[i],&sv[i]); 126 add(su[i],sv[i]); 127 add(sv[i],su[i]); 128 } 129 scc=0;top=0;TT=0; 130 memset(dfn,0,sizeof(dfn)); 131 for(int i=1;i<=n;i++) 132 if(!dfn[i]) 133 tarjan(i); 134 135 Build(m); 136 137 int u=bfs(1); 138 int v=bfs(u); 139 printf("%d\n",scc-q[scc-1].c); 140 } 141 return 0; 142 } 143 /* 144 8 9 145 1 2 146 2 3 147 3 4 148 4 1 149 5 6 150 6 7 151 7 8 152 8 5 153 4 5 154 155 8 8 156 1 2 157 2 3 158 3 4 159 5 6 160 6 7 161 7 8 162 8 5 163 4 5 164 165 8 8 166 1 2 167 2 3 168 3 4 169 2 5 170 5 6 171 6 7 172 7 8 173 8 6 174 175 8 9 176 1 2 177 2 3 178 3 4 179 2 5 180 5 6 181 6 7 182 7 8 183 8 6 184 4 5 185 186 7 8 187 1 2 188 2 3 189 3 4 190 4 5 191 5 6 192 6 1 193 3 7 194 7 4 195 */