Codeforces 1187 G - Gang Up
思路:
每个点按时间拆点建边,然后跑最小费用流
一次走的人不能太多,假设每次走的人为k
(k*k-(k-1)*(k-1))*d <= c+d
k <= 24
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head int n, m, k, c, d, a[], x, y;
const int N = + ;
const int INF = 0x3f3f3f3f;
struct edge {
int to, cap, cost, rev;
};
int V;
vector<edge>g[N];
int h[N], dis[N], prevv[N], preve[N];
void add_edge(int u, int v, int cap, int cost) {
g[u].pb({v, cap, cost, g[v].size()});
g[v].pb({u, , -cost, g[u].size()-});
}
int min_cost_flow(int s, int t, int f) {
int res = ;
mem(h, );
while(f > ) {
priority_queue<pii, vector<pii>, greater<pii> > q;
mem(dis, 0x3f);
dis[s] = ;
q.push({, s});
while(!q.empty()) {
pii p = q.top();
q.pop();
int v = p.se;
if(dis[v] < p.fi) continue;
for (int i = ; i < g[v].size(); ++i) {
edge &e = g[v][i];
if(e.cap > && dis[e.to] > dis[v] + e.cost + h[v] - h[e.to]) {
dis[e.to] = dis[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
preve[e.to] = i;
q.push({dis[e.to], e.to});
}
}
}
if(dis[t] == INF) return -;
for (int v = ; v < V; ++v) h[v] += dis[v];
int d = f;
for (int v = t; v != s; v = prevv[v]) d = min(d, g[prevv[v]][preve[v]].cap);
f -= d;
res += d*h[t];
for (int v = t; v != s; v = prevv[v]) {
edge &e = g[prevv[v]][preve[v]];
e.cap -= d;
g[v][e.rev].cap += d;
}
}
return res;
}
int s, t;
int main() {
scanf("%d %d %d %d %d", &n, &m, &k, &c, &d);
for (int i = ; i <= k; ++i) scanf("%d", &a[i]);
s = , t = *n+;
for (int i = ; i <= k; ++i) add_edge(s, (a[i]-)*+, , );
for (int i = ; i <= ; ++i) add_edge(i, t, k, );
for (int i = ; i <= n; ++i) {
for (int j = ; j < ; ++j)
add_edge((i-)*+j, (i-)*+j+, k, c);
}
for (int i = ; i <= m; ++i) {
scanf("%d %d", &x, &y);
for (int j = ; j < ; ++j) {
for (int k = ; k <= ; ++k) {
add_edge((x-)*+j, (y-)*+j+, , (k*k-(k-)*(k-))*d+c);
add_edge((y-)*+j, (x-)*+j+, , (k*k-(k-)*(k-))*d+c);
}
}
}
V = *n+;
printf("%d\n", min_cost_flow(s, t, k));
return ;
}
Codeforces 1187 G - Gang Up的更多相关文章
- [codeforces 549]G. Happy Line
[codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...
- CodeForces 794 G.Replace All
CodeForces 794 G.Replace All 解题思路 首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\), ...
- Codeforces 1207 G. Indie Album
Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...
- codeforces 659 G. Fence Divercity 组合数学 dp
http://codeforces.com/problemset/problem/659/G 思路: f(i,0/1,0/1) 表示到了第i个,要被切的块开始了没有,结束了没有的状态的方案数 递推看代 ...
- Codeforces 803 G. Periodic RMQ Problem
题目链接:http://codeforces.com/problemset/problem/803/G 大致就是线段树动态开节点. 然后考虑到如果一个点还没有出现过,那么这个点显然未被修改,就将这个点 ...
- Codeforces 954 G. Castle Defense
http://codeforces.com/problemset/problem/954/G 二分答案 检验的时候,从前往后枚举,如果发现某个位置的防御力<二分的值,那么新加的位置肯定是越靠后越 ...
- Codeforces 746 G. New Roads
题目链接:http://codeforces.com/contest/746/problem/G mamaya,不知道YY了一个什么做法就这样过去了啊 2333 首先我显然可以随便构造出一棵树满足他所 ...
- Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS
G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...
- codeforces 626 G. Raffles(线段树+思维+贪心)
题目链接:http://codeforces.com/contest/626/problem/G 题解:这题很明显买彩票肯定要买贡献最大的也就是说买p[i]*(num[i]+1)/(num[i]+a[ ...
随机推荐
- elasticsearch查询操作
#查看节点信息 curl -X GET http://localhost:9200/_nodes #打开文件数信息 curl -X GET http://localhost:9200/_nodes/s ...
- 《MIT 6.828 Lab 1 Exercise 12》实验报告
本实验的网站链接:MIT 6.828 Lab 1 Exercise 12. 题目 Exercise 12. Modify your stack backtrace function to displa ...
- poj1410(判断线段和矩形是否相交)
题目链接:https://vjudge.net/problem/POJ-1410 题意:判断线段和矩形是否相交. 思路:注意这里的相交包括线段在矩形内,因此先判断线段与矩形的边是否相交,再判断线段的两 ...
- Python解Leetcode: 1. Two Sum
题目描述:求出数组中等于目标值的两个数的索引,假定肯定存在两个数并且同一个索引上的数不能用两次. 思路: 用空间换时间,使用一个字典存储已经遍历的数字的索引,如果新遍历的数字和target的差值在字典 ...
- selenium获取标签中的文本
# 寻找文本所在的标签waitClickCompanyName = driver.find_elements_by_xpath('//div[@id="nsrzt"]//li') ...
- 【Python基础】05_Python中的while循环
1.程序的三大流程介绍 顺序 —— 从上到下,顺序执行 分支 —— 根据条件判断,决定代码的分支 循环 —— 让特定代码执行 2.while 基本语法 while 条件(判断 计数器 是否达到 目标次 ...
- Idea加载项目扫描完毕后自动退出
问题描述:Idea平时好好的,突然就打开后扫描完毕后自动退出.网上说修改idea.exe.vmoptions文件的Xmx,还是不行. 后来根据http://www.pianshen.com/artic ...
- 通过ADB调试安卓程序
ADB,即 Android Debug Bridge,它是Android开发/测试人员不可替代的强大工具. 1.下载ADB后,将以下四个文件放到某个文件夹下即可.因为打开Cmd默认路径是 C:\Use ...
- Js 判断数组中是否包含某个值
includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false. JavaScript Array includes() 方法
- 远程连接windows2003桌面无法使用剪切板的有效解决方法
远程桌面控制服务器时,无法剪切.粘贴一些东西,上网搜了一下,原来是rdpclip.exe(remote desktop clipboard)不起作用了.此程序负责管理本地机与远程服务器之间共享剪切板, ...