博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[APIO2010]巡逻 题解
阅读量:4473 次
发布时间:2019-06-08

本文共 2118 字,大约阅读时间需要 7 分钟。

题目:;

题目大意:一棵树,添加k条边使得遍历所有的点的总代价最小,其中1<=k<=2;

首先呢:不建道路,路线总长度2*(n-1);

我们分析当k等于1,此时的最优解无疑是将边加到直径两端;那么答案就是2*(n-1)-d+1;这样你会得到30分;

其实我们考虑k=2时,对于一棵树,我们加边会形成一个环,加两条边形成两个环,我们就要考虑这两个环的关系了;

1.两个环上的边不重叠;

2.两个环上的边有重叠部分;

对于第一种情况,我们只需要再次找一下最长链,忽略直径哈,答案减小;

那么对于第二种,如果我们将其作为加1条边的请况,那么两个环重叠的不会将不会被经过,和题目要求不符,重叠部分则需要经过两次,所以我们需要让巡逻车在适当时候重新巡逻这些边,并且返回,最终的结果是我们让两个环上的重叠的边经过了两次;

所以:

1、求树的直径L1,将L1上的边权取反,变为-1;

2、再求树的直径L2,答案即为2(n−1)−L1+1−L2+1=2∗n−L1−L2;

如果L2这条直径包含L1取反的部分,就相当于重叠,减掉(L1-1),重叠的边经过了一次,减掉(L2-1),把重叠部分加回来,变为需要经过两次;

时间复杂度O(N);

对于找树的直径,有bfs(dfs)和dp两种做法:

但是bfs的做法遇到负权好像不太行,但是dp可以,但是dp好像只可以求个直径;

#include
using namespace std;#define N 500010template
inline void read(T &x){ x=0;T f=1,ch=getchar(); while(!isdigit(ch)) {
if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x*=f;}struct gg { int y,next,v;}a[N<<1];int lin[N],vis[N],dis[N],dis1[N],father[N],tot=1,n,k,ans,d,x1,x2;inline void add(int x,int y,int z) { a[++tot].next=lin[x]; a[tot].y=y; a[tot].v=z; lin[x]=tot;}queue
q;inline int bfs(int s) { memset(vis,0,sizeof(vis)); int point=s; q.push(s); dis[s]=0;vis[s]=1; father[s]=0; while(!q.empty()) { int x=q.front();q.pop(); for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; if(!vis[y]) { vis[y]=1;q.push(y); dis[y]=dis[x]+a[i].v; father[y]=x; if(dis[point]
dis[x2]) { x1=father[x1]; vis[x1]=1; ++d; } while (x1!=x2) { x1=father[x1]; x2=father[x2]; vis[x1]=vis[x2]=1; d+=2; }}inline void tab(int x) { for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; if(y!=father[x]) { if(vis[x]&&vis[y]) { a[i].v=a[i^1].v=-1; } tab(y); } }}int main() { //freopen("data.in","r",stdin); //freopen("data.ans","w",stdout); read(n);read(k); int x,y; for(int i=1;i
View Code

 

 

转载于:https://www.cnblogs.com/Tyouchie/p/10808247.html

你可能感兴趣的文章
看雪CTF 2016( 原:CrackMe攻防大赛) 第一题分析
查看>>
JavaWeb--中文乱码
查看>>
二叉树——套路化解题--1.最大搜索二叉子树
查看>>
python测试工程师高端基础面试题整理
查看>>
梳理一下 html 中的一些基本概念
查看>>
SQL Server 2008 备份数据库
查看>>
ab测试 uwsgi遇到的问题
查看>>
Beanstalkd
查看>>
ThreadLocal工作原理
查看>>
Unity5 官方教程笔记(2D Rogue Like)02 —— BoardManager
查看>>
设计模式
查看>>
u-boot2011.09 启动流程记录
查看>>
c#中如何跨线程调用windows窗体控件?
查看>>
opencv相关
查看>>
UPC 2188 Balls(DP)
查看>>
重组索引(带统计索引重组时间)
查看>>
Linux&UNIX上卸载GoldenGate的方法
查看>>
HTML语义化标签
查看>>
Java实现HTML转PDF的总结
查看>>
人工智能实战_第三次作业_田博
查看>>