hdu 4871 树的分治+最短路记录路径
来源:互联网 发布:网络拓扑环形结构 编辑:程序博客网 时间:2024/06/05 11:18
/*题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数。解:1、求出最短路径树--spfa加记录 2、树上进行操作--树的分治,分别处理子树进行补集等运算*/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<iostream>#include<queue>#define ll __int64using namespace std;#define N 31000#define inf 10000000000000000ll kk;struct node {ll u,v,w,next;}bian[N*4];ll yong,head[N];void init() {yong=0;memset(head,-1,sizeof(head));}void addedge(ll u,ll v,ll w) {bian[yong].u=u;bian[yong].v=v;bian[yong].w=w;bian[yong].next=head[u];head[u]=yong++;}ll Min(ll v,ll vv) {return v>vv?vv:v;}ll premi[N],val[N];//用来记录前一个元素的字典序最小和前一条边的权值void spfa(ll u,ll n) { ll i,cur,dis[N],vis[N]; queue<ll>q; for(i=1;i<=n;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); memset(premi,-1,sizeof(premi)); dis[u]=0; q.push(u); while(!q.empty()) { cur=q.front(); q.pop(); vis[cur]=0; for(i=head[cur];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(dis[v]>dis[cur]+bian[i].w) { dis[v]=dis[cur]+bian[i].w; val[v]=bian[i].w; premi[v]=cur;//记录前一个节点 if(!vis[v]) { vis[v]=1; q.push(v); } } else if(dis[v]==dis[cur]+bian[i].w) { if(premi[v]==-1)premi[v]=cur; else premi[v]=Min(premi[v],cur); } } } return ;}/*以下是树的分治部分*/ll minn,ma,num[N],nn,diss[N],len,mxx,mxnum,vis[N],ed[N];void dfs1(ll u,ll fa) {ll i;nn++;for(i=head[u];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(v!=fa&&!vis[v]) dfs1(v,u);}return ;}ll Max(ll v,ll vv) {return v>vv?v:vv;}void dfs2(ll u,ll fa) {num[u]=1;ll i,tit=0;for(i=head[u];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(v!=fa&&!vis[v]) { dfs2(v,u); num[u]+=num[v]; tit=Max(tit,num[v]); }}tit=Max(tit,nn-num[u]);if(tit<minn) { minn=tit; ma=u;}return;}void dfs4(ll u,ll fa,ll w,ll aa) { diss[++len]=w; ed[len]=aa; ll i; for(i=head[u];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(v!=fa&&!vis[v]) dfs4(v,u,w+bian[i].w,aa+1); } return;}struct nodee {//用来记录补集 ll dis; ll num;}f[N];void dfs3(ll u) { ll i,k,j; if(nn<kk)return ; for(i=0;i<=nn;i++) f[i].dis=0,f[i].num=0; for(i=head[u];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(vis[v])continue; len=0; // printf("v=%I64d w=%I64d\n",v,bian[i].w); dfs4(v,-1,bian[i].w,1);//因为这里实际是两个节点但是要把它看成一个节点 // printf("len=%I64d\n",len); for(j=1;j<=len;j++) { // printf("z%I64d %I64d %I64d\n",j,ed[j],diss[j]); if(ed[j]+1==kk) {//和当前子树比较 if(diss[j]>mxx) { mxx=diss[j]; mxnum=1; } else if(diss[j]==mxx) mxnum++; } if(kk-ed[j]-1<=0)continue; k=diss[j]+f[kk-ed[j]].dis;//补集 // printf("khe=%I64d\n",k); if(k>mxx) { mxx=k; mxnum=f[kk-ed[j]].num; } else if(k==mxx) mxnum+=f[kk-ed[j]].num; } for(j=1;j<=len;j++) {//加入补集 if(ed[j]+1>=kk)continue; if(f[ed[j]+1].dis<diss[j]) {//节点数要加一加入 f[ed[j]+1].dis=diss[j]; f[ed[j]+1].num=1; } else if(f[ed[j]+1].dis==diss[j]) f[ed[j]+1].num++; } } //printf("%I64d %I64d\n",mxx,mxnum); return ;}void dfs(ll u) { minn=inf; nn=0; dfs1(u,-1); dfs2(u,-1); //printf("minn=%I64d %I64d\n",minn,ma); vis[ma]=1; dfs3(ma); ll i; for(i=head[ma];i!=-1;i=bian[i].next) { ll v=bian[i].v; if(!vis[v]) dfs(v); } return;}int main() { ll t,n,m,i,j,k; scanf("%I64d",&t); while(t--) { init(); scanf("%I64d%I64d%I64d",&n,&m,&kk); while(m--) { scanf("%I64d%I64d%I64d",&i,&j,&k); addedge(i,j,k); addedge(j,i,k); } if(kk==1) {//是1的时候特殊处理 printf("0 %I64d\n",n); continue; } spfa(1,n);//求最短路 //prllf("z"); init(); for(i=2;i<=n;i++) {//建立最短路径树 addedge(i,premi[i],val[i]); addedge(premi[i],i,val[i]); } // for(i=0;i<yong;i++) // printf("%I64d %I64d %I64d\n",bian[i].u,bian[i].v,bian[i].w); memset(vis,0,sizeof(vis)); mxx=-1;mxnum=0;//用来记录最长值和路径数 dfs(1); printf("%I64d %I64d\n",mxx,mxnum); }return 0;}
0 0
- hdu 4871 树的分治+最短路记录路径
- HDU 4871 Shortest-path tree 最短路+树的点分治
- 【BZOJ4016】最短路径树问题,最短路+点分治
- 最短路 记录路径
- hdu 1385 Minimum Transport Cost(最短路+记录路径)
- HDU 1385 Minimum Transport Cost【最短路之路径记录】
- HDU 4871 Shortest-path tree (树分治之点分治 最短路径树问题)
- hdu 4871 Shortest-path tree(最短路+点分治)
- 【HDU】4871 Shortest-path tree 最短路+点分治
- HDU 4871 Shortest-path tree (最短路+树上点分治)
- 最短路+记录路径+变形!!
- 城市间紧急救援 ,复杂点的最短路,记录路径,记录最短路个数等
- hdu 3790 最短路径问题(多权值的最短路)
- BZOJ 4016 最短路径树问题 [最短路+树分治]
- bzoj 4016: [FJOI2014]最短路径树问题 最短路+点分治
- [最短路径] HDU 2544 - 最短路
- uva 11374 最短路+记录路径 dijkstra最短路模板
- hdu 1245 Saving James Bond 策画几何+最短路 最短路求步数最少的路径
- Oracle的数据字典和动态性能视图
- C++中函数指针的运用
- 【软考】数据结构
- Unit 3: Reading
- 我与C++设计模式(十三)——策略模式
- hdu 4871 树的分治+最短路记录路径
- Java注释模板
- 黑马程序员——Java基础---静态变量与实例变量的区别
- C++ sort与qsort的比较
- 小白学c++之继承、动态绑定
- Unit 3: Subjects
- Unit 3: Verbs
- java.sql.date 跟java.util.date的区别 和怎么在oracle数据库中显示时分秒
- 重装VS2013之后加载opencv项目失败