您的位置:首页 > 其它

【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党哦。然后由于懒得码就。。。嘿嘿嘿

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: