hdu 4679Terrorist’s destroy
来源:互联网 发布:四大名助 知乎 编辑:程序博客网 时间:2024/05/16 08:55
给出一棵树,这棵树有N个点,N-1条边,正好是一个无向无环树,切去一条边,形成两棵树,使之这两棵树的最长路与切去边的权值最小,实践证明,用vector更加耗时,多了一秒,所以自己的写的链表更好
改进后的算法(耗时八百多毫秒):#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>#include <algorithm>using namespace std;#pragma comment(linker,"/STACK:1024000000,1024000000")#define N 100010struct node{ int v; int index; int next;};node G[N*2];int n,p,M_A_X,_v,_u;bool dp[N],vis[N];int Sum[N][3], cnt[N][3],next[N],arr[N],s[N],head[N];void add(int u,int v,int id){ G[p].v=v; G[p].index=id; G[p].next=head[u]; head[u]=p++;}int max_max(int x,int y){ return x>y?x:y;}void bfs(int cur,int pos){ queue<int> q; q.push(cur); dp[cur]=1; while(!q.empty()) { int u=q.front(); q.pop(); if(!pos) _u=u; else _v=u; for(int i=head[u]; i!=-1; i=G[i].next) { int c=G[i].v; if(!dp[c]) { q.push(c),dp[c]=1; if(pos) next[c]=u;; } } }}void dfs(int u,int v){ if(dp[u]) return; dp[u]=1; for(int i=head[u]; i!=-1; i=G[i].next) if(G[i].v!=v) { if(dp[G[i].v]) continue; dfs(G[i].v,-1); int m=Sum[G[i].v][1]+1; if(Sum[u][1]<m) { Sum[u][2]=Sum[u][1]; Sum[u][1]=m; } else if(Sum[u][2]<m) Sum[u][2]=m; Sum[u][0]=max_max(Sum[u][0],max_max(Sum[u][1]+Sum[u][2],Sum[G[i].v][0])); }}void trajan(int u,int v){ if(dp[u]) return; dp[u]=1; int c; bool flag=0; for(int i=head[u]; i!=-1; i=G[i].next) if(G[i].v!=v) { if(dp[G[i].v]) continue; trajan(G[i].v,-1); int m=cnt[G[i].v][1]+1; if(cnt[u][1]<m) { cnt[u][2]=cnt[u][1]; cnt[u][1]=m; } else if(cnt[u][2]<m) cnt[u][2]=m; cnt[u][0]=max_max(cnt[u][0],max_max(cnt[u][1]+cnt[u][2],cnt[G[i].v][0])); } else flag=1,c=i; if(flag) { vis[G[c].index]=1; int m=max_max(cnt[u][0],Sum[v][0])*s[G[c].index]; if(M_A_X>m||(M_A_X==m&&G[c].index<p)) { M_A_X=m; p=G[c].index; } }}void solve(int cur){ int c=0; arr[0]=cur; for(int v=next[cur]; v!=-1; v=next[v]) { dfs(arr[c],v); Sum[v][1]=Sum[arr[c]][1]+1; Sum[v][0]=max_max(Sum[arr[c]][0],Sum[v][1]); arr[++c]=v; } memset(dp,0,sizeof(bool)*(n+1)); for(int i=c-1; i>=0; --i) { int q=arr[i+1],v=arr[i]; trajan(q,v); cnt[v][1]=cnt[q][1]+1; cnt[v][0]=max_max(cnt[v][1],cnt[q][0]); } for(int i=1; i<n; ++i) if(!vis[i]&&(s[i]*c<M_A_X||(s[i]*c==M_A_X&&p>i))) { M_A_X=s[i]*c; p=i; }}int main(){ // freopen("in.txt","r",stdin); // freopen("ou.txt","w",stdout); int t,cou=1; scanf("%d",&t); while(t--) { scanf("%d",&n); int u,v,w; for(int i=0; i<=n; ++i) { dp[i]=vis[i]=0; Sum[i][0]=Sum[i][1]=Sum[i][2]=0; cnt[i][0]=cnt[i][1]=cnt[i][2]=0; head[i]=next[i]=-1; } p=0; for(int i=1; i<n; ++i) { scanf("%d%d%d",&u,&v,&w); add(u,v,i); add(v,u,i); s[i]=w; } bfs(1,0); memset(dp,0,sizeof(bool)*(n+1)); bfs(_u,1); memset(dp,0,sizeof(bool)*(n+1)); M_A_X=0x7fffffff; p=-1; solve(_v); printf("Case #%d: %d\n",cou++,p); } return 0;}以前的算法(耗时一千九百多毫秒):#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <algorithm>using namespace std;#pragma comment(linker,"/STACK:1024000000,1024000000")struct node{ int v; int w; int index; node(int u,int x,int y) { v=u; w=x; index=y; }};vector<node> G[100011];int s[100011];int n,p,M_A_X,_v,_u;bool dp[100011],vis[100011];int Sum[100011][3], cnt[100011][3],next[100011],arr[100011];int max_max(int x,int y){ return x>y?x:y;}void bfs(int cur,int pos){ queue<int> q; q.push(cur); dp[cur]=1; while(!q.empty()) { int u=q.front(); q.pop(); if(!pos) _u=u; else _v=u; for(int i=G[u].size()-1; i>=0; --i) { int c=G[u][i].v; if(!dp[c]) { q.push(c),dp[c]=1; if(pos) next[c]=u;; } } }}void dfs(int u,int v){ if(dp[u]) return; dp[u]=1; for(int i=G[u].size()-1; i>=0; --i) if(G[u][i].v!=v) { if(dp[G[u][i].v]) continue; dfs(G[u][i].v,-1); int m=Sum[G[u][i].v][1]+1; if(Sum[u][1]<m) { Sum[u][2]=Sum[u][1]; Sum[u][1]=m; } else if(Sum[u][2]<m) Sum[u][2]=m; Sum[u][0]=max_max(Sum[u][0],max_max(Sum[u][1]+Sum[u][2],Sum[G[u][i].v][0])); }}void trajan(int u,int v){ if(dp[u]) return; dp[u]=1; int c; bool flag=0; for(int i=G[u].size()-1; i>=0; --i) if(G[u][i].v!=v) { if(dp[G[u][i].v]) continue; trajan(G[u][i].v,-1); int m=cnt[G[u][i].v][1]+1; if(cnt[u][1]<m) { cnt[u][2]=cnt[u][1]; cnt[u][1]=m; } else if(cnt[u][2]<m) cnt[u][2]=m; cnt[u][0]=max_max(cnt[u][0],max_max(cnt[u][1]+cnt[u][2],cnt[G[u][i].v][0])); } else flag=1,c=i; if(flag) { vis[G[u][c].index]=1; int m=max_max(cnt[u][0],Sum[v][0])*G[u][c].w; if(M_A_X>m||(M_A_X==m&&G[u][c].index<p)) { M_A_X=m; p=G[u][c].index; } }}void solve(int cur){ int c=0; arr[0]=cur; for(int v=next[cur]; v!=-1; v=next[v]) { dfs(arr[c],v); Sum[v][1]=Sum[arr[c]][1]+1; Sum[v][0]=max_max(Sum[arr[c]][0],Sum[v][1]); arr[++c]=v; } memset(dp,0,sizeof(bool)*(n+1)); for(int i=c-1; i>=0; --i) { int q=arr[i+1],v=arr[i]; trajan(q,v); cnt[v][1]=cnt[q][1]+1; cnt[v][0]=max_max(cnt[v][1],cnt[q][0]); } for(int i=1; i<n; ++i) if(!vis[i]&&(s[i]*c<M_A_X||(s[i]*c==M_A_X&&p>i))) { M_A_X=s[i]*c; p=i; }}int main(){ // freopen("in.txt","r",stdin); // freopen("ou.txt","w",stdout); int t,cou=1; scanf("%d",&t); while(t--) { scanf("%d",&n); int u,v,w; for(int i=0; i<=n; ++i) { G[i].clear(); dp[i]=vis[i]=0; Sum[i][0]=Sum[i][1]=Sum[i][2]=0; cnt[i][0]=cnt[i][1]=cnt[i][2]=0; next[i]=-1; } for(int i=1; i<n; ++i) { scanf("%d%d%d",&u,&v,&w); G[u].push_back(node(v,w,i)); G[v].push_back(node(u,w,i)); s[i]=w; } bfs(1,0); memset(dp,0,sizeof(bool)*(n+1)); bfs(_u,1); memset(dp,0,sizeof(bool)*(n+1)); M_A_X=0x7fffffff; p=-1; solve(_v); printf("Case #%d: %d\n",cou++,p); } return 0;}
- HDU 4679 Terrorist’s destroy
- HDU 4679 Terrorist’s destroy
- HDU 4679 Terrorist’s destroy
- hdu 4679 Terrorist’s destroy
- hdu-4679-Terrorist’s destroy
- hdu 4679Terrorist’s destroy
- HDU 4679 Terrorist’s destroy
- HDU 4679 Terrorist’s destroy【Tree】
- HDU 4679 Terrorist’s destroy 解题报告
- HDU 4679 Terrorist’s destroy (树形DP)
- HDU 4679 Terrorist’s destroy(树形dp | 多校8)
- hdu 4679 Terrorist’s destroy (树形dp)
- hdu 4679 Terrorist’s destroy 多校第八场
- HDU 4679 Terrorist’s destroy (拆边+树的直径)
- hdu 4679 Terrorist’s destroy ( 树形dp 树的直径 )
- hdu 4679 Terrorist’s destroy(树形dp)
- hdu 4679 Terrorist’s destroy (DP or 树直径,4级)
- hdu 4679 Terrorist’s destroy 树形dp水题 (2013多校联合)
- ARM板和Linux上的3G配置详解
- 断言assert是一个宏
- 怎么让网站站内文章秒收录
- hdu 4686 Arc of Dream
- 传统网络技术杂记
- hdu 4679Terrorist’s destroy
- 华晨中华H330似曾相识别处来
- c++ 全局/局部变量/常量声明/定义(二)
- svn 常见报错
- csdn博客积分详解
- C#WinForm如何在TreeView上面绑定checkbox
- Quartus II 管脚配置
- 数学之路(3)-机器学习(3)-机器学习算法-PCA
- MongoDB——第五天 主从复制