【luoguP1453】城市环路
来源:互联网 发布:java memcached 使用 编辑:程序博客网 时间:2024/06/09 19:40
题目背景
一座城市,往往会被人们划分为几个区域,例如住宅区、商业区、工业区等等。B市就被分为了以下的两个区域——城市中心和城市郊区。在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市中心。
题目描述
整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路。保证环上任意两点有且只有2条路径互通。图中的其它部分皆隶属城市郊区。
现在,有一位名叫Jim的同学想在B市开店,但是任意一条边的2个点不能同时开店,每个点都有一定的人流量Pi,在该点开店的利润就等于该店的人流量Pi×K(K≤10000),K的值将给出。
Jim想尽量多的赚取利润,请问他应该在哪些地方开店?
输入输出格式
输入格式:第一行一个整数N 代表城市中点的个数。城市中的N个点由0~N-1编号。
第二行N个正整数,表示每个点的人流量Pi(Pi≤10000)。
下面N行,每行2个整数A,B,表示A,B建有一条双向路。
最后一行一个实数K。
输出格式:一个实数M,(保留1位小数),代表开店的最大利润。
输入输出样例
41 2 1 50 10 21 21 32
12.0
说明
【数据范围】
对于20%的数据 N≤100.
对于50%的数据 N≤2000.
对于100%的数据 N≤100000(环上的点不超过2000个).
这题是相当的坑。。。
坑点相当恶心
先说一下题解:
这题其实是一道非常显然的DP
然后我们对于其他不在环上的点,可以发现可以树形DP预处理出来
然后然后就只剩下了一个环,
直接跑环形DP就好了
然后对于起点,选和不选要跑两遍
接下来说一下坑点:
如果有想到了O(环上的点^2)的算法,写完代码交了以后就会和我一样惊奇地发现
这题数据环上的点并没有保证不超过2000个!!!!!!!
我搞了一个晚上才发现这一点。。。。。。。
PS.这题蒟蒻发现和以前写的环形DP不一样,只需要一个起点跑一次就好了,仔细想想以后发现原来是以前的写过的环形DP出发点不一样会产生不同结果
代码:
#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<cstdlib>#include<vector>#include<queue>#include<stack>using namespace std;typedef long long LL;typedef double DL;const int maxn = 200100;vector<int> e[maxn];queue<int> Q;DL p[maxn],a[maxn][2],f[maxn][2],k;bool vis[maxn],exist[maxn],flag = 0;int pre[maxn],stk[maxn],top,point[maxn],tot;int n;inline LL getint(){ LL ret = 0,f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar(); return ret * f;}inline void find(int u,int fa){ vis[u] = 1; stk[++top] = u; for (int i = 0; i < e[u].size(); i++) { int v = e[u][i]; if (flag) return; if (v == fa) continue; if (vis[v]) { while (stk[top] != v) { exist[stk[top]] = 1; point[++tot] = stk[top--]; } exist[stk[top]] = 1; point[++tot] = stk[top--]; flag = 1; return; } find(v,u); } stk[top] = 0; top--; return;}inline void init(int u,int fa){ a[u][1] = p[u] * k; for (int i = 0; i < e[u].size(); i++) { int v = e[u][i]; if (v == fa) continue; if (exist[v]) continue; init(v,u); a[u][0] += max(a[v][1],a[v][0]); a[u][1] += a[v][0]; }}int main(){ n = getint(); for (int i = 1; i <= n; i++) p[i] = getint(); for (int i = 1; i <= n; i++) { int u = getint() + 1,v = getint() + 1;// int u = getint(),v = getint(); e[u].push_back(v); e[v].push_back(u); } scanf("%lf",&k); memset(vis,0,sizeof(vis)); find(1,0); memset(vis,0,sizeof(vis)); for (int i = 1; i <= n; i++) init(i,0); DL ans = 0; n = tot; f[1][0] = a[point[1]][0]; f[1][1] = 0; for (int j = 2; j <= n; j++) { f[j][1] = f[j - 1][0] + a[point[j]][1]; f[j][0] = max(f[j - 1][1],f[j - 1][0]) + a[point[j]][0]; } ans = max(ans,max(f[n][1],f[n][0])); f[1][0] = 0; f[1][1] = a[point[1]][1]; for (int j = 2; j <= n; j++) { f[j][1] = f[j - 1][0] + a[point[j]][1]; f[j][0] = max(f[j - 1][1],f[j - 1][0]) + a[point[j]][0]; } ans = max(ans,f[n][0]); printf("%.1lf",ans); return 0;}
- 【luoguP1453】城市环路
- 洛谷 P1453 城市环路
- 网络环路
- 环路地址
- 网络环路
- 城市
- 城市
- 城市
- 城市
- 《城市》
- 单链表判断环路及环路的入口
- 路由环路的产生
- 环路滤波一些概念
- ERPS环路保护
- 二层环路产生
- 环路公路难题
- RIP环路避免概述
- 北京九环路
- HDU6077 2017杭电多校联赛第四场-Time To Get Up
- (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
- 集合深浅拷贝以及经常遇到的坑
- C++学习之string类
- 自定义View画圆并移动
- 【luoguP1453】城市环路
- oracle 数据库突然宕机 解决办法
- js字符串
- OpenCV学习之形态学操作
- Linux上编译安装Apache出现httpd: Could not reliably determine the server's fully qualified domain name
- WebRTC之语音活动检测(VAD)算法
- volatile关键字以及C语言的其它31个关键字
- 最少转弯问题(又是BFS,但就喜欢用矩阵)
- mac系统Shadowsocks更新pac