【noip暑假tarjan专题】
2016-07-08 16:13
435 查看
%%%奎老师
A:傻逼缩点。。。傻逼编译器卡我next。。。
B:就是这道奎老师没讲清楚的题,明明小朋友们都一A嘛,,,明明细节有很多嘛,,,怎么都这么熟练啊。
C:本质还是B,换了个马甲而已。
D:又是缩点,缩完点之后每个入度为1的强连通分量找一下最小值就好啦。。。
I:这就是在求桥了,ok现在来总结一下,有向图中缩点叫强连通分量,求桥与割点,LCA都是在无向图中。然后我又求错了,我在求桥的时候直接算了权值差。。。。看了网上题解,还是乖乖缩点+树形dp吧。。。。QAQ【这里做了双联通之后,就不用求桥啦】有重边,要注意以下。
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define N 50000 using namespace std; int edgenum,n,edgenew,m,all,flag,tm,bian,ans,id,top; int jie ,num ,p ,head ,size ,vet ,uu ,vv ,yt ,low ,dfn ,a ,headnew ,vetnew ,nextnew ,stack ; void add(int u,int v) { edgenum++;vet[edgenum]=v;jie[edgenum]=head[u];head[u]=edgenum; } void tarjan(int u,int fa) { tm++;dfn[u]=low[u]=tm;top++;stack[top]=u; int e=head[u];int flag=0; while(e>0) { int v=vet[e]; if(v==fa&&flag==0){ flag=1;e=jie[e];continue; } if(dfn[v]==0)tarjan(v,u); low[u]=min(low[u],low[v]);//printf("low==%d %d\n",u,v); e=jie[e]; } if(dfn[u]==low[u]){ id++;num[id]+=a[u];yt[u]=id; while(stack[top]!=u) { int k=stack[top];yt[k]=id;num[id]+=a[k]; top--; }top--; } } void Add(int u,int v) { edgenew++;vetnew[edgenew]=v;nextnew[edgenew]=headnew[u];headnew[u]=edgenew; //printf("add====%d %d\n",u,v); } void dp(int u,int fa) { int e=headnew[u];size[u]=num[u]; //printf("%d\n",u); while(e>0) { int v=vetnew[e];//printf("%d\n",v); if(v!=fa)dp(v,u),size[u]+=size[v]; e=nextnew[e]; } int x=all-size[u];x=x-size[u];if(x<0)x=-x; ans=min(ans,x); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { edgenum=0;edgenew=0;memset(headnew,0,sizeof(headnew)); memset(head,0,sizeof(head));memset(p,0,sizeof(p));memset(num,0,sizeof(num));memset(size,0,sizeof(size)); all=0;tm=0;bian=0;id=top=0; memset(low,0,sizeof(low));memset(dfn,0,sizeof(dfn)); for(int i=1;i<=n;i++)scanf("%d",&a[i]),all+=a[i];int u,v; for(int i=1;i<=m;i++)scanf("%d%d",&u,&v),u++,v++,uu[i]=u,vv[i]=v,add(u,v),add(v,u); tarjan(1,0); //for(int i=1;i<=n;i++)printf("id==%d\n",low[i]); if(id==1){ printf("impossible\n");continue; } for(int i=1;i<=m;i++) { u=yt[uu[i]],v=yt[vv[i]]; if(u!=v)Add(u,v),Add(v,u); } ans=1000000000; dp(1,0); printf("%d\n",ans); } return 0; }双联通
J: 来自hdu2460.。。。。。网上随手找个std发现都是暴力。。。这个世界太不真诚了。
题意大概是求加上新边后桥的数目。。。。这里需要求LCA。。。和双连通分量。
P:树上的LCA,网上90percent的题解用这种做法都会MLE。。。晕。。。不过最后还是过了,有个蛮坑的点是求自己和自己的lca
顺便发现自己连倍增法求LCA都忘了。有空练。
T:这个是真的,不作死就不会死。听说这道题在罗oj交过哦,听说我当时还是p党哦。然后由于懒得码就。。。嘿嘿嘿
相关文章推荐
- cocos2dx中的声音
- 删除vector指定下标的元素
- DAG图与拓扑排序
- Layer3 OSPF网络类型和LSA1、2
- 工作环境配置
- opencv等待函数
- Oracle中SUBSTR与SUBSTRB的区别
- ubuntu安装openssh-server 报依赖错误的解决过程 ubuntu自带的有openssh-client,所以可以通过 1 ssh username@host 来远程连接linux 可
- myeclipse+maven实现多模块项目struts+spring+mybatis
- django常用命令
- UVA - 10420 List of Conquests
- Python的作用域
- 一个简单的守护进程的编写
- 停止线程的两种方法
- Win10 MXNet跑一个实例
- UVA - 340 Master-Mind Hints
- Android简易实战教程--第五话《开发一键锁屏应用》
- Android简易实战教程--第五话《开发一键锁屏应用》
- Android多线程编程AsyncTask
- Codeforces 689 C The Values You Can Make(dp)