Warm up HDU
来源:互联网 发布:广告算法工程师招聘 编辑:程序博客网 时间:2024/05/16 15:20
题意:n个点,m条无向边。如果去掉一条边,使图不连通,那么这条边就称之为桥。可以加一条边,使图中的桥最少,这个时候桥为多少?
题解:先缩点,缩完之后是一棵树,树的边都是桥。然后求树的直径,将直径相连是最优的。ans=树的边数-直径的长度。
分析:
之前只写过有向图的缩点。这个缩点和有向图差不多,加一个标记就行了。注意这里还要将桥都记下来,然后重新建图。
例子:
6 8
1 2
2 3
3 4
4 5
2 6
6 2
1 3
4 7
有环,不会扫完所有点。
那个异或的用法,强…
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <map>using namespace std;#define ll long long#define mem(a,b) memset(a,b,sizeof(a))const int maxn = 200010;const int maxm = 1000010;int sd[maxn],rd[maxn],cd[maxn],dian[maxn],head[maxn],low[maxn],dfn[maxn],st[maxn],vis_st[maxn];int bb[maxm][2],d[maxn],vis[maxn],top=0,tot=0,num=0,numb=0;struct node{ int to,pre,flag;}e[maxm*2];void ini(){ mem(st,0);mem(bb,0);mem(d,0);mem(vis,0);mem(dfn,0);mem(low,0);mem(vis_st,0);mem(e,0);mem(sd,0);mem(rd,0);mem(cd,0);mem(dian,0);mem(head,-1); top=0,tot=0,num=0,numb=0;}void addedge(int h,int a,int b){ e[h].to=b;e[h].pre=head[a];e[h].flag=1;head[a]=h;}void Tarjan(int u){ st[++top]=u; dfn[u]=low[u]=++tot; vis_st[u]=1; for(int i=head[u];i>-1;i=e[i].pre) { node t=e[i]; if(!e[i].flag) continue; e[i].flag=e[i^1].flag=0; if(!dfn[t.to]) { Tarjan(t.to); low[u]=min(low[u],low[t.to]); if(dfn[u]<low[t.to]) { bb[numb][0]=u;bb[numb++][1]=t.to; } } else {if(vis_st[t.to]) low[u]=min(low[u],low[t.to]);} } if(dfn[u]==low[u]) { sd[num++]=u; int a; do{ a=st[top--]; vis_st[a]=0; dian[a]=u; }while(u!=a); }}void dfs(int u,int h){ vis[u]=1; for(int i=head[u];i>-1;i=e[i].pre) { int t=dian[e[i].to]; if(!vis[t]) dfs(t,h+1); } d[u]=h;}int main(){ int N,M,maxx=0,k=0; while(scanf("%d %d",&N,&M)!=EOF&&N+M) { ini();int h=0; num=top=tot=0,maxx=0,k=0;; for(int i=0;i<M;i++) { int a,b; scanf("%d %d",&a,&b); addedge(h,a,b);h++; addedge(h,b,a);h++; } for(int i=1;i<=N;i++) if(!dfn[i]) Tarjan(i); mem(e,0);h=0;mem(vis,0);mem(d,0);mem(head,-1); for(int i=0;i<numb;i++){ addedge(h,dian[bb[i][0]],dian[bb[i][1]]);h++; addedge(h,dian[bb[i][1]],dian[bb[i][0]]);h++; } dfs(dian[1],0);k=dian[1]; for(int i=0;i<num;i++) if(maxx<d[sd[i]]) {maxx=d[sd[i]];k=sd[i];} mem(vis,0);mem(d,0); dfs(k,0);maxx=0; for(int i=0;i<num;i++) if(maxx<d[sd[i]]) maxx=d[sd[i]]; printf("%d\n",num-maxx-1); } return 0;}
阅读全文
0 0
- hdu 4612 Warm up
- HDU 4612 Warm up
- hdu 4612 Warm up
- hdu 4612Warm up
- HDU 4612 Warm up
- HDU 4612 Warm up
- Warm up HDU
- hdu 4612 Warm up
- Warm up HDU
- hdu 4619 Warm up 2
- HDU 4619 Warm up 2
- HDU 4619 Warm up 2
- hdu 4619 Warm up 2
- HDU 4619 Warm up 2
- HDU 4619 Warm up 2
- hdu - 4619 - Warm up 2
- HDU-4619-Warm up 2
- hdu 4619 Warm up 2
- java AWT事件处理
- poj3255Roadblocks之dijkstra解法
- 是否应该买点股票?企业的价值和股票的价值
- 添加语音播报功能
- 周计划 补完工程 第十二周 matlab 练习
- Warm up HDU
- 设计模式_策略模式(16)
- 单词翻转
- WebServer服务器原理(例子)
- Android 6.0 运行时权限处理 二维码开发
- QTcpSocket 通讯 ( 服务器、客户端、封包、解包 )
- java开发/10.1-10.3/邓聪
- 微信公众号title替换
- Java编程思想读书笔记——持有对象