codevs 1218 疫情控制
啊好烦这道题。。。。
基本思路网上都有。
注意的一点是在匹配的时候,如果有军队的来源没有被匹配到,那么就先匹配这个来源。(因为不花钱)。
不过数据好水。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 50050
#define maxe 100500
using namespace std;
int n,x,y,z,g[maxv],nume=,m,c[maxv],anc[maxv][],dis[maxv][],l=,r=,disr[maxv],kr=,fath[maxv];
int top=,cnt=;
bool vis[maxv],ret[maxv];
struct edge
{
int v,w,nxt;
}e[maxe];
struct status
{
int val,id;
}regis[maxv],stack[maxv];
bool cmp(status a,status b)
{
return a.val<b.val;
}
void addedge(int u,int v,int w)
{
e[++nume].v=v;
e[nume].w=w;
e[nume].nxt=g[u];
g[u]=nume;
}
void dfs1(int x,int father)
{
if (father==) fath[x]=x;
else if (x!=) fath[x]=fath[father];
for (int i=g[x];i;i=e[i].nxt)
{
int v=e[i].v;
if (v!=father)
{
anc[v][]=x;dis[v][]=e[i].w;
disr[v]=disr[x]+e[i].w;r=max(r,disr[v]);
dfs1(v,x);
}
}
}
bool dfs2(int x,int father)
{
if (vis[x]) return true;
int cnt1=,cnt2=;
for (int i=g[x];i;i=e[i].nxt)
{
int v=e[i].v;
if (v!=father)
{
cnt1++;
if (dfs2(v,x)) cnt2++;
}
}
if ((cnt1==cnt2) && (cnt1!=)) return true;
return false;
}
void get_table()
{
r+=kr;
for (int i=;i<=;i++)
for (int j=;j<=n;j++)
{
anc[j][i]=anc[anc[j][i-]][i-];
dis[j][i]=dis[j][i-]+dis[anc[j][i-]][i-];
}
}
int get_pnt(int x,int r)
{
for (int i=;i>=;i--)
{
if (r>=dis[x][i])
{
r-=dis[x][i];
x=anc[x][i];
}
}
return x;
}
bool check(int x)
{
memset(vis,false,sizeof(vis));
memset(ret,false,sizeof(ret));
top=;cnt=;
for (int i=;i<=m;i++)
{
int v=c[i];
if (disr[v]<x)
{
top++;
stack[top].val=x-disr[v];
stack[top].id=fath[v];
}
else if (disr[v]==x) vis[fath[v]]=true;
else vis[get_pnt(v,x)]=true;
}
for (int i=g[];i;i=e[i].nxt)
{
int v=e[i].v;
if (!dfs2(v,))
{
regis[++cnt].val=disr[v];
regis[cnt].id=v;
ret[v]=true;
}
}
if (top<cnt) return false;
sort(stack+,stack+top+,cmp);
sort(regis+,regis+cnt+,cmp);
int p1=,p2=;
while ((p2<=cnt) && (p1<=top))
{
if (ret[stack[p1].id]) {ret[stack[p1].id]=false;p1++;}
else
{
while ((!ret[regis[p2].id]) && (p2<=cnt)) p2++;
while ((stack[p1].val<regis[p2].val) && (p1<=top)) p1++;
if (p2==cnt+) break;
if (p1==top+) break;
ret[regis[p2].id]=false;p1++;p2++;
}
}
for (int i=g[];i;i=e[i].nxt)
{
int v=e[i].v;
if (ret[v]) return false;
}
return true;
}
int get_ans()
{
int ans;
while (l<=r)
{
int mid=(l+r)>>;
if (check(mid)) {ans=mid;r=mid-;}
else l=mid+;
}
return ans;
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n-;i++)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
addedge(y,x,z);
if ((x==) || (y==)) kr=max(kr,z);
}
scanf("%d",&m);
for (int i=;i<=m;i++)
scanf("%d",&c[i]);
dfs1(,);
get_table();
printf("%d\n",get_ans());
return ;
}
codevs 1218 疫情控制的更多相关文章
- Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...
- 【NOIP2012】 疫情控制
[NOIP2012] 疫情控制 标签: 倍增 贪心 二分答案 NOIP Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- [NOIP2012]疫情控制 贪心 二分
题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...
- 疫情控制 blockade
疫情控制 blockad 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当 ...
- codevs1218 疫情控制
疫情控制(blockade.cpp/c/pas)[问题描述]H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点.H 国的首都爆发了一种危害 ...
- 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- CH6301 疫情控制
6301 疫情控制 0x60「图论」例题 描述 H国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病. ...
- luoguP1084 疫情控制(题解)(搜索+贪心)
luoguP1084 疫情控制 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...
随机推荐
- Objective-C传递数据小技巧
转自:http://www.guokr.com/blog/203413/ 比如说,如果你想向UIAlertView的delegate方法中传递一些信息,怎么办?继承UIAlertView么?使用Cat ...
- css的transition 属性
把鼠标指针放到 div 元素上,其宽度会从 100px 逐渐变为 300px: div { width:100px; transition: width 2s; -moz-transition: wi ...
- 【转载】CCombobox使用大全
一.如何添加/删除Combo Box内容 1. 在Combo Box控件属性的Data标签里面添加,一行表示Combo Box下拉列表中的一行.换行用ctrl+回车. 2. 在程序初始化时动态添加 如 ...
- hdu 4888
网络流建模,建模不难,难在找环: #include<cstdio> #include<algorithm> #include<vector> #include< ...
- synergy--共享你的键鼠
synergy用来分享一套键鼠,作用于多台主机.可作用于linux.Windows和mac平台.工作方式是:将一台主机作为服务器端,然后服务器端将会分享自己的键鼠,另一台主机作为客户端连接服务端就可以 ...
- HDU 4509 湫湫系列故事——减肥记II(暴力模拟即可)
看了题目后,没自己做,直接看别人题解了,这里转一下. 看了之后,突然想起scanf还可以按照自己写的格式输入数据啊,差点连这个都忘记了啊. 注意输入中时间可能有重复的. http://www.cnbl ...
- POJ 1716
#include <iostream> #include <algorithm> #define MAXN 20005 using namespace std; int _m[ ...
- Linux Shell 数字计算与比较
直接上脚本, 使用$(())以及$[]进行数字计算 数值比较:n1 -eq n2检查n1是否等于n2 n1 -le n2检查n1是否小于等于n2n1 -ge n2检查n1是否大于等于n ...
- fhq_treap 总结
今天跟着zcg大神学了一发fhq_treap 发现在维护区间问题上fhq_treap不仅思维量小,而且代码量更小 是Splay的不错的替代品,不过至今还是有一些问题不能很好的解决 譬如查询某个数在序列 ...
- SpringMVC学习总结(三)——Controller接口详解(2)
4.5.ServletForwardingController 将接收到的请求转发到一个命名的servlet,具体示例如下: package cn.javass.chapter4.web.servle ...