2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
来源:互联网 发布:淘宝老店铺 编辑:程序博客网 时间:2024/06/05 14:33
有一个大家都会的D。 emmm。我不会 但是!队友会呀2333先放放
-update:2017年10月16日20:49:39
A - Admiral
题意:给一张带权图,让你求出从s到t两条完全不同的路径的权值加和最小为多少。
思路:网络流。拆点入门题。s点和t点内部流量为2,其余为1。跑最小费用最大流即可。
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 2 * 1000 + 5;const int INF = 0x3f3f3f3f;typedef pair<int, int>pii;struct MCMF{ int n,m; struct Edge{int from, to, cap, flow, cost;}; vector<Edge> edge; vector<int> g[MAXN]; bool inq[MAXN]; int d[MAXN]/*spfa*/, pre[MAXN]/*上一条弧*/, a[MAXN]/*可改进量*/; void init(int n){ this->n = n; for(int i = 1; i <= n; i++) g[i].clear(); edge.clear(); } void addedge(int from, int to, int cap, int cost) { edge.push_back({from,to,cap,0,cost}); edge.push_back({to,from,0,0,-cost}); m = edge.size(); g[from].push_back(m-2); g[to].push_back(m-1); } bool spfa(int s, int t, int& flow, LL& cost) { for(int i = 1; i <= n; i++) inq[i] = 0, d[i] = INF; d[s] = 0, inq[s] = true, pre[s] = 0, a[s] = INF; queue<int> q; q.push(s); while(!q.empty()) { int u = q.front();q.pop(); inq[u] = false; for(int i = 0; i < g[u].size(); i++) { Edge& e = edge[g[u][i]]; if(e.cap > e.flow && d[e.to] > d[u]+e.cost) { d[e.to] = d[u]+e.cost; pre[e.to] = g[u][i]; a[e.to] = min(a[u], e.cap-e.flow); if(!inq[e.to]) q.push(e.to), inq[e.to] = true; } } } if(INF == d[t]) return false; flow += a[t]; cost += (LL)d[t]*(LL)a[t]; for(int u = t; u != s; u = edge[pre[u]].from) { edge[pre[u]].flow += a[t]; edge[pre[u]^1].flow -= a[t]; } return true; } //需要保证初始网络没有负圈,返回最大流量,cost才是最小花费 int mincostmaxflow(int s, int t, LL & cost) { int flow = 0; cost = 0; while(spfa(s,t,flow,cost)); return flow; }}mcmf;int main(){ int vs, es; while(~scanf("%d%d", &vs, &es)) { mcmf.init(vs << 1); for(int i = 2; i < vs; i++) mcmf.addedge(i, i + vs, 1, 0); mcmf.addedge(1, vs + 1, 2, 0); mcmf.addedge(vs, vs << 1, 2, 0); for(int i = 0; i < es; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); mcmf.addedge(a + vs, b, 1, c); } long long ans = 0; mcmf.mincostmaxflow(1, vs << 1, ans); printf("%lld\n", ans); } return 0;}
B - Beer Pressure(搜索+哈希状态)
题意:给你n个人已获得的票数,告诉你参与投票的人总人数为K,问你每个人赢得最后获选的概率是多少。每个人投票时,投票概率不等价,投第i个人的概率为,第i个人当前获得票数/当前已投票人数。如果最后k票投完,有人同为票数最高者,平分胜率。(
n≤5 ,k≤50 )
思路:相当于一个dp[a][b][c][d][e],每一维度皆为50,看上去是
#include <bits/stdc++.h>using namespace std;const int base = 51;int n, k, pub[10], temp[10];double ans[10];inline long long calc(int a[]){ long long ret = 0; for(int i = 0; i < n; i++) ret = ret * base + a[i]; return ret;}int main(){ while(~scanf("%d%d", &n, &k)) { for(int i = 0; i < n; i++) ans[i] = 0; for(int i = 0; i < n; i++) scanf("%d", &pub[i]); unordered_map<long long, double>pro; queue<long long>que; que.push(calc(pub)); pro[calc(pub)] = 1.0; while(que.size()) { long long cur = que.front();que.pop(); long long tot = 0; for(int i = 0; i < n; i++) temp[n - 1 - i] = cur % base, cur /= base, tot += temp[n - 1 - i]; long long st = calc(temp); if(tot == k) { int mx = *max_element(temp, temp + n); int cnt = count(temp, temp + n, mx); for(int i = 0; i < n; i++) if(temp[i] == mx) ans[i] += 1.0 / cnt * pro[st]; continue; } for(int i = 0; i < n; i++) { double p = 1.0 * temp[i] / tot; temp[i]++; long long fst = calc(temp); if(pro[fst] == 0) que.push(fst); pro[fst] += pro[st] * p; temp[i]--; } } for(int i = 0; i < n; i++) printf("pub %d: %.2f %%\n", i + 1, ans[i] * 100); } return 0;}
E - Edge Case
思路:写了几个发现感觉是斐波那契数列,直接加了个大数类A了。
I - Idol
2-SAT板子题。
#include <bits/stdc++.h>using namespace std;const int maxn = 2000 + 5;vector<int>G[maxn];int pre[maxn];int lowlink[maxn];//lowlink[u]:u及其后代能追溯到的最早祖先点v的pre[v]的值。int sccno[maxn], dfs_clock, scc_cnt;stack<int>S;void Tarjan(int u){ pre[u] = lowlink[u] = ++dfs_clock; S.push(u); for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(pre[v] == 0) { Tarjan(v); lowlink[u] = min(lowlink[u], lowlink[v]); } else if(!sccno[v]) { lowlink[u] = min(lowlink[u], pre[v]); } } if(lowlink[u] == pre[u]) { scc_cnt++; for(;;) { int x = S.top();S.pop(); sccno[x] = scc_cnt; if(x == u) break; } }}void find_scc(int n){ dfs_clock = scc_cnt = 0; memset(sccno, 0, sizeof(sccno)); memset(pre, 0, sizeof(pre)); for(int i = 1; i <= n; i++) { if(pre[i] == 0) Tarjan(i); }}int n, m;int ans[maxn];pair<int, int>a[maxn];bool solve(){ memset(ans, 0, sizeof(ans)); for(int i = 1; i <= n; i++) { if(sccno[i] == sccno[i + n]) return false; } int flag = 0; if(sccno[1] > sccno[1 + n]) flag = 1; for(int i = 1; i <= n; i++) { if(flag) ans[i] = (sccno[i] > sccno[i + n]); else ans[i] = (sccno[i] < sccno[i + n]); } for(int i = 0; i < m; i++) { int x = a[i].first, y = a[i].second; int jx = (x > 0), jy = (y > 0); x = abs(x), y = abs(y); if((ans[x] != jx) && (ans[y] != jy)) return false; } return true;}int main(){ while(~scanf("%d%d", &n, &m)) { for(int i = 1; i <= 2 * n; i++) G[i].clear(); for(int i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); a[i] = {x, y}; if(x > 0 && y > 0)//x && y G[x + n].push_back(y), G[y + n].push_back(x); else if(x < 0 && y < 0) { x = abs(x), y = abs(y); G[x].push_back(y + n), G[y].push_back(x + n); } else if(x > 0 && y < 0) { y = abs(y); G[x + n].push_back(y + n); G[y].push_back(x); } else if(x < 0 && y > 0) { swap(x, y); y = abs(y); G[x + n].push_back(y + n); G[y].push_back(x); } } find_scc(2 * n); if(solve()) puts("yes"); else puts("no"); } return 0;}
J - Joint Venture
题意:给你n个数,问你里头有没有两个加和为x的。(
0≤n≤1e6 ,x≤1e8 )
思路:水题,小心一个a[i] == x - a[i]的特判即可。
K - Key Insight
题意:给你两串字符,然后告诉你长度k为一段,串一串二在每一段中一一对应,得到若干种对应方案,然后问你整个串中有多少种方案使得,所有段均满足。
思路:先按题意连边,同一段中,相同的两个字母连边。又易得,两点之间只有边数==段数,才应该在新图中连边。得到新图以后,直接搜联通块,联通块为偶数即可。(易证,今年多校也有一个这种题)然后每个联通块的贡献度即为其大小siz/2的阶乘。
#include <bits/stdc++.h>using namespace std;char s1[105], s2[105];int pre[205][205], in[205], vis[205];vector<int>G[205];int siz = 0;int dfs(int u){ vis[u] = 1; int ret = 1; for(auto o : G[u]) if(vis[o] == 0) ret += dfs(o); return ret;}long long fac(int siz){long long ret = 1;for(int i = 1; i <= siz; i++) ret *= i; return ret;};int main(){ int block; while(~scanf("%d", &block)) { memset(vis, 0, sizeof(vis)); memset(pre, 0, sizeof(pre)); for(int i = 0; i <= 200; i++) G[i].clear(); scanf("%s%s", s1 + 1, s2 + 1); int len = strlen(s1 + 1); int need = len / block; for(int i = 1; i <= len; i += block) { for(int j = 0; j < block; j++) { for(int k = 0; k < block; k++) { if(s1[j + i] == s2[k + i]) { pre[j + 1][k + 1 + block]++, pre[k + 1 + block][j + 1]++; } } } } for(int i = 1; i <= block * 2; i++) { for(int j = block + 1; j <= block * 2; j++) { if(pre[i][j] >= need) { G[i].push_back(j); G[j].push_back(i); in[i]++, in[j]++; } } } long long ans = 1; for(int i = 1; i <= block; i++) { if(vis[i]) continue; int siz = dfs(i); if(siz & 1) ans = 0; else ans *= fac(siz/2); } printf("%I64d\n", ans); } return 0;}
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
- 2014-2015 Northwestern European Regional Contest (NWERC 2014)【solved:7 / 11】
- 2013-2014 Northwestern European Regional Contest (NWERC 2013)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 补题
- 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 7/11 待补
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E. Elementary Math
- C-Cleaning Pipes(判断两线段相交+二分图判定) 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest 训练总结 【5+2】【待补】
- 2015-2016 Northwestern European Regional Contest I.Identifying Map Tiles(超级技巧+脑洞)
- 并查集 xtu-2170 ACM ICPC 2011–2012, Northeastern European Regional Contest Problem E. Eve
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) K题(dp)
- 2008-2009 ACM-ICPC Northeastern European Regional Contest (NEERC 08) (2013区域赛练习)
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) I题Crane
- 2006 ACM Northwestern European Programming Contest C题(二分求最大)
- Southeastern European Regional Programming Contest 2010 D Problemsetting
- 2014-2015 ACM-ICPC Northeastern European Regional Contest (NEERC 14)
- 负载均衡基础知识
- 从ttf原始文件解析出字体名称时遇到的字节序的问题是big endian
- Android官方DataBinding(十一):对双向绑定之反向绑定的改进和简化
- python gutenberg古腾堡语料库
- HttpClient大并发下Timeout waiting for connection from pool 问题解决方案
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
- nginx 安装及基本命令
- RecyclerView 添加动画,以及快速滑动导致的问题
- Holiday节假日信息系统的开发(零)--序言
- java常用包之util 包
- 蓝牙4.0BLE抓包(二) – 广播包解析
- 四大线程池详解
- 类比C#、JavaScript和Java的集合数据处理
- Service启动过程and新进程创建全过程源码分析