bupt summer training for 16 #6 ——图论
https://vjudge.net/contest/174020
A.100条双向边,每个点最少连2个边
所以最多100个点,点的标号需要离散化
然后要求恰好经过n条路径
快速幂,乘法过程就是floyed就行了
#include <algorithm>
#include <cstring>
#include <cstdio> using namespace std; const int maxn = ; int n, m, s, t, b, c[]; struct matrix {
int c[][];
matrix() {
memset(c, 0x3f, sizeof c);
}
void add(int u, int v, int w) {
c[u][v] = c[v][u] = w;
}
matrix operator * (const matrix &a) const {
matrix b;
for(int k = ;k <= n;k ++)
for(int i = ;i <= n;i ++)
for(int j = ;j <= n;j ++)
b.c[i][j] = min(b.c[i][j], c[i][k] + a.c[k][j]);
return b;
}
matrix operator ^ (int &k) {
matrix b = *this;
for(k --;k > ;k >>= , *this = (*this) * (*this))
if(k & ) b = b * (*this);
return b;
}
}; int main() {
matrix g;
int u, v, w;
scanf("%d %d %d %d", &n, &m, &s, &t);
while(m --) {
scanf("%d %d %d", &w, &u, &v);
if(!c[u]) c[u] = ++ b;
if(!c[v]) c[v] = ++ b;
g.add(c[u], c[v], w);
}
swap(b, n);
printf("%d", (g ^ b).c[c[s]][c[t]]);
return ;
}
B.
C.非常裸的生成树计数问题
其实谁是最高管理层并没什么卵用
想当然理解了读入,垃圾题目有重边
注意有重边,整数行列式计算可以拿来当板子了
#include <algorithm>
#include <cstring>
#include <cstdio> using namespace std; const int maxn = ; int n, m, s, t, b, c[]; struct matrix {
int c[][];
matrix() {
memset(c, 0x3f, sizeof c);
}
matrix(int x) {
memset(c, , sizeof c);
for(int i = ;i <= n;i ++)
c[i][i] = ;
}
void add(int u, int v, int w) {
c[u][v] = c[v][u] = w;
}
matrix operator * (const matrix &a) const {
matrix b;
for(int k = ;k <= n;k ++)
for(int i = ;i <= n;i ++)
for(int j = ;j <= n;j ++)
b.c[i][j] = min(b.c[i][j], c[i][k] + a.c[k][j]);
return b;
}
matrix operator ^ (int &k) {
matrix b = *this;
for(k --;k > ;k >>= , *this = (*this) * (*this))
if(k & ) b = b * (*this);
return b;
}
}; int main() {
matrix g;
int u, v, w;
scanf("%d %d %d %d", &n, &m, &s, &t);
while(m --) {
scanf("%d %d %d", &w, &u, &v);
if(!c[u]) c[u] = ++ b;
if(!c[v]) c[v] = ++ b;
g.add(c[u], c[v], w);
}
swap(b, n);
printf("%d", (g ^ b).c[c[s]][c[t]]);
return ;
}
D.
E.高中做过的网络流模型
每行被隔开的算一块,st向这些块连边流量为1
因为这样一个块里最多放一个棋子
每列被隔开的算一块,这些块向en连边流量为1,道理同上
行块和列快相遇出可以放旗子,那么它们连一条边流量为1
因为只有一个位置
求个最大流...这样一说直接二分图上匈牙利就可以了...
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = , maxm = , inf = 0x3f3f3f3f; int s, t, len = , g[maxn]; struct edge {
int to, cap, next;
}e[maxm]; int p[maxn], q[maxn], d[maxn]; void add(int u, int v, int w) {
e[++ len] = (edge){v, w, g[u]}, g[u] = len;
e[++ len] = (edge){u, , g[v]}, g[v] = len;
} bool bfs() {
int l = , r = , x, i;
memset(d, , sizeof d);
d[s] = , q[] = s;
while(l <= r) {
x = q[l ++];
for(i = g[x];i;i = e[i].next)
if(e[i].cap && !d[e[i].to])
d[e[i].to] = d[x] + , q[++ r] = e[i].to;
}
return d[t];
} int dfs(int x, int y) {
if(x == t || y == ) return y;
int flow = ;
for(int &i = p[x];i;i = e[i].next) {
if(!e[i].cap || d[e[i].to] != d[x] + ) continue;
int f = dfs(e[i].to, min(y, e[i].cap));
flow += f, y -= f;
e[i].cap -= f, e[i ^ ].cap += f;
if(!y) break;
}
return flow;
} int dinic() {
int maxflow = ;
while(bfs()) {
memcpy(p, g, sizeof g);
maxflow += dfs(s, inf);
}
return maxflow;
} int n, m, cnt; char str[][]; int mmp[][]; int main() {
t = ;
while(~scanf("%d", &n)) {
m = ;
memset(g, , sizeof g);
for(int i = ;i <= n;i ++)
scanf("%s", str[i] + );
for(int i = ;i <= n;i ++) {
for(int j = ;j <= n;j ++) {
if(str[i][j] == 'X') mmp[i][j] = -;
else {
if(j == || str[i][j - ] == 'X') m ++, add(s, m, );
mmp[i][j] = m;
}
}
}
for(int j = ;j <= n;j ++)
for(int i = ;i <= n;i ++) {
if(str[i][j] != 'X') {
if(i == || str[i - ][j] == 'X') m ++, add(m, t, );
add(mmp[i][j], m, inf);
}
}
printf("%d\n", dinic());
}
}
F.裸的最短路,当然你要看到这是
单向边!!!
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; const int maxn = ; queue <int> q; int n, m, k, t, d[maxn], vis[maxn]; vector <pair<int, int> > e[maxn]; int main(){
while(~scanf("%d %d %d", &n, &m, &k)) {
for(int i = ;i <= n;i ++) d[i] = 0x3f3f3f3f, e[i].clear();
for(int u, v, w, i = ;i <= m;i ++) {
scanf("%d %d %d", &u, &v, &w);
e[u].push_back(make_pair(v, w));
//e[v].push_back(make_pair(u, w));
}
scanf("%d", &t);
for(int j, i = ;i <= t;i ++)
scanf("%d", &j), d[j] = , q.push(j);
while(!q.empty()) {
int u = q.front();
q.pop(), vis[u] = ;
for(int i = ;i < e[u].size();i ++) {
if(d[e[u][i].first] > d[u] + e[u][i].second) {
d[e[u][i].first] = d[u] + e[u][i].second;
if(!vis[e[u][i].first]) vis[e[u][i].first] = , q.push(e[u][i].first);
}
}
}
printf("%d\n", d[k] == 0x3f3f3f3f ? - : d[k]);
}
return ;
}
G.裸MST,稠密图没有卡 Kruskal,良心!
#include <cstdio>
#include <algorithm> using namespace std; struct edge {
int u, v, w;
bool operator < (const edge &a) const {
return w < a.w;
}
}e[]; int n, f[]; int find_(int x) {
if(f[x] != x) return f[x] = find_(f[x]);
return x;
} int main() {
while(~scanf("%d", &n)) {
int m = , ans = ;
for(int k, i = ;i <= n;i ++) {
f[i] = i;
for(int j = ;j <= i;j ++) scanf("%d", &k);
for(int j = i + ;j <= n;j ++) scanf("%d", &k), e[++ m] = (edge){i, j, k};
}
sort(e + , e + m + );
for(int u, v, i = , j = ;j < n;i ++) {
u = find_(e[i].u), v = find_(e[i].v);
if(u == v) continue;
f[v] = u, j ++, ans += e[i].w;
}
printf("%d\n", ans);
}
return ;
}
H.
I.经典网络流模型
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = , maxm = , inf = 0x3f3f3f3f; int s, t, len = , g[maxn]; struct edge {
int to, cap, next;
}e[maxm]; int p[maxn], q[maxn], d[maxn]; void add(int u, int v, int w) {
e[++ len] = (edge){v, w, g[u]}, g[u] = len;
e[++ len] = (edge){u, , g[v]}, g[v] = len;
} bool bfs() {
int l = , r = , x, i;
memset(d, , sizeof d);
d[s] = , q[] = s;
while(l <= r) {
x = q[l ++];
for(i = g[x];i;i = e[i].next)
if(e[i].cap && !d[e[i].to])
d[e[i].to] = d[x] + , q[++ r] = e[i].to;
}
return d[t];
} int dfs(int x, int y) {
if(x == t || y == ) return y;
int flow = ;
for(int &i = p[x];i;i = e[i].next) {
if(!e[i].cap || d[e[i].to] != d[x] + ) continue;
int f = dfs(e[i].to, min(y, e[i].cap));
flow += f, y -= f;
e[i].cap -= f, e[i ^ ].cap += f;
if(!y) break;
}
return flow;
} int dinic() {
int maxflow = ;
while(bfs()) {
memcpy(p, g, sizeof g);
maxflow += dfs(s, inf);
}
return maxflow;
} int Case, n, m, sum; int main() {
scanf("%d", &Case);
for(int tt = ;tt <= Case;tt ++) {
sum = , len = ;
memset(g, , sizeof g);
printf("Case #%d: ", tt);
scanf("%d %d", &n, &m), t = n + m + ;
for(int j, i = ;i <= n;i ++)
scanf("%d", &j), add(s, i, j), sum += j;
for(int j, i = ;i <= m;i ++)
scanf("%d", &j), add(n + i, t, j);
for(int k, j, i = ;i <= n;i ++) {
scanf("%d", &k);
while(k --) {
scanf("%d", &j);
add(i, n + j + , inf);
}
}
for(int k, i = ;i <= m;i ++)
for(int j = ;j <= m;j ++) {
scanf("%d", &k);
if(k) add(n + i, n + j, inf);
}
printf("%d\n", sum - dinic());
}
return ;
}
J.随便做的傻逼题,我写的算麻烦的
#include <cstdio>
#include <algorithm> using namespace std; int n, a[]; int main() {
scanf("%d", &n);
for(int i = ;i <= n;i ++)
scanf("%d", &a[i]);
int l = , r = n;
while(!a[l] && l <= n) l ++;
while(!a[r] && r >= ) r --;
if(l > r) puts("");
else {
int ans = , last = ;
for(int i = l + ;i <= r;i ++) {
if(a[i]) {
ans ++;
if(last != ) last = ;
}
else {
if(last != ) {
if(i < r && !a[i + ]) last = ;
else ans ++;
}
}
}
printf("%d\n", ans);
}
return ;
}
bupt summer training for 16 #6 ——图论的更多相关文章
- bupt summer training for 16 #8 ——字符串处理
https://vjudge.net/contest/175596#overview A.设第i次出现的位置左右端点分别为Li,Ri 初始化L0 = 0,则有ans = sum{ (L[i] - L[ ...
- bupt summer training for 16 #7 ——搜索与DP
https://vjudge.net/contest/174962#overview A.我们发现重点在于x,y只要累加就ok了 在每个x上只有上下两种状态,所以可以记忆化搜索 f[0/1][i]表示 ...
- bupt summer training for 16 #5 ——数据结构
https://vjudge.net/contest/173780 A.假设 Pt = i,则由Ppi = i得 Ppt = t = Pi 所以就有 if Pt = i then Pi = t #in ...
- bupt summer training for 16 #4 ——数论
https://vjudge.net/contest/173277#overview A.平方差公式后变为 n = (x + y)(x - y) 令 t = x - y ,变成 n = (t + 2x ...
- bupt summer training for 16 #3 ——构造
https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 #include <cstdio> #include &l ...
- bupt summer training for 16 #2 ——计算几何
https://vjudge.net/contest/171368#overview A.一个签到题,用叉积来判断一个点在一条线的哪个方向 可以二分,数据范围允许暴力 #include <cst ...
- bupt summer training for 16 #1 ——简单题目
D.What a Mess 给n个数,求其中能满足 a[i] % a[j] == 0 的数对之和 n = 1W,max_ai = 100W 不是很大,所以就直接筛就可以了 计算可得最高复杂度 < ...
- 【Android Developers Training】 16. 暂停和恢复一个Activity
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- BUPT2017 springtraining(16) #6 ——图论
题目链接 A.容易发现最后字符的对应都是一对一的 或者说我们没办法出现最后多对一或者一对多的情况 所以只要算出 ‘a’ - 'z' 每个字符最后对应的字符即可 #include <cstdio& ...
随机推荐
- iframe高度100%,自适应高度
声明:有更好的方法在下一篇内容中 100% http://www.360doc.com/content/11/1102/15/55892_161105115.shtml iframe自适应高度 转自: ...
- Coursera Algorithms week4 基础标签表 练习测验:Check if a binary tree is a BST
题目原文: Given a binary tree where each
- jqxtree异步加载部门树
整体思路 A.要想实现异步加载第一次加载的是一级部门 B.加载一级部门,如果有子部门,部门前面带+号,没有子部门,部门前面没有+号(+号也就是点击可以展开) C.在sql中实现如果有子部门默认都加载一 ...
- Java基础学习经验分享
很多人学习Java,尤其是自学的人,在学习的过程中会遇到各种各样的问题以及难点,有时候卡在一个点上可能需要很长时间,因为你在自学的过程中不知道如何去掌握和灵活运用以及该注意的点.下面我整理了新手学习可 ...
- Offer收割_4
1.水题 2.BFS宽搜(使用优先队列priority_queue) 4.题意:给数组a.要求重排列数组,使得数组中的任意相邻的两个元素不同.如果存在多个方案,那么选择字典序最小的方案. 如果不能满 ...
- Unity学习-元素类型(三)
在看下面操作时,先记住三句话 1.游戏对象 是由 组件 组成的:衣服 2.材质(Material):就是衣服的设计方案 3.纹理(Texture):做衣服的布料 从GameObject到Cube 第一 ...
- Python随笔-字符串
函数title.lower.upper. ct = "hello WORLD" print(ct.title()) #title 以首字母大写的方式显示每个单词 print(ct. ...
- SAS进阶《深入解析SAS》之Base SAS基础、读取外部数据到SAS数据集
SAS进阶<深入解析SAS>之Base SAS基础.读取外部数据到SAS数据集 前言:在学习完<SAS编程与商业案例>后,虽然能够接手公司的基本工作,但是为了更深入的SAS学习 ...
- 01--TCP状态转换
参考大牛文章: http://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html
- JS高级——函数的调用模式
函数调用模式一共有四种 <script> //1.函数模式 //this指向window全局对象 //2.方法模式 //this指向调用这个方法的对象 //3.构造函数模式 //this ...