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 ——图论的更多相关文章

  1. bupt summer training for 16 #8 ——字符串处理

    https://vjudge.net/contest/175596#overview A.设第i次出现的位置左右端点分别为Li,Ri 初始化L0 = 0,则有ans = sum{ (L[i] - L[ ...

  2. bupt summer training for 16 #7 ——搜索与DP

    https://vjudge.net/contest/174962#overview A.我们发现重点在于x,y只要累加就ok了 在每个x上只有上下两种状态,所以可以记忆化搜索 f[0/1][i]表示 ...

  3. 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 ...

  4. bupt summer training for 16 #4 ——数论

    https://vjudge.net/contest/173277#overview A.平方差公式后变为 n = (x + y)(x - y) 令 t = x - y ,变成 n = (t + 2x ...

  5. bupt summer training for 16 #3 ——构造

    https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 #include <cstdio> #include &l ...

  6. bupt summer training for 16 #2 ——计算几何

    https://vjudge.net/contest/171368#overview A.一个签到题,用叉积来判断一个点在一条线的哪个方向 可以二分,数据范围允许暴力 #include <cst ...

  7. bupt summer training for 16 #1 ——简单题目

    D.What a Mess 给n个数,求其中能满足 a[i] % a[j] == 0 的数对之和 n = 1W,max_ai = 100W 不是很大,所以就直接筛就可以了 计算可得最高复杂度 < ...

  8. 【Android Developers Training】 16. 暂停和恢复一个Activity

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. BUPT2017 springtraining(16) #6 ——图论

    题目链接 A.容易发现最后字符的对应都是一对一的 或者说我们没办法出现最后多对一或者一对多的情况 所以只要算出 ‘a’ - 'z' 每个字符最后对应的字符即可 #include <cstdio& ...

随机推荐

  1. openstack 杂记 备忘002

  2. 基于Hive的手机应用信息统计分析系统

    目录 项目概要 具体实现 HIVE查询 项目概要 需求 手机应用日志 定期离线分析手机应用新增用户.活跃用户.沉默用户.启动次数.版本分布和留存用户等业务指标. 工作流程 手机APP启动时,上报启动日 ...

  3. 在LNMP或Nginx上配置NameCheap免费SSL证书

  4. 如何判断js的变量的数据类型

    文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般的Js中类型检测的方法,实际上是每个新手在构建Js知识体系时,都要知晓的,而我只是 ...

  5. Lambda表达式怎么写SQL中的in?

    ambda表达式查询没有IN这个方法,可以变通一下,in查询的数组是否包含在映射对象里面的集合里 直接贴代码吧,一看就懂了 class Program { static void Main(strin ...

  6. jmeter关联、下载文件、简单压测

    关联 一.什么是关联 关联是请求与请求之间存在数据依赖关系,需要从上一个请求获取下一个请求需要回传回去的数据. 简单地说就是在测试过程中有些数据的值会经常发生变化,要获取并使用这些数据,把这个动态的信 ...

  7. Servlet访问路径的两种方式、Servlet生命周期特点、计算服务启动后的访问次数、Get请求、Post请求

    Servlet访问路径的两种方式: 1:注解 即在Servlet里写一个@WebServlet @WebServlet("/myServlet") 2:配置web.xml < ...

  8. SQL 循环插入10000条

    SQL> create table tt_test ( x int, y char(50) ); Table created. SQL> SQL> begin 2 for i in ...

  9. vm装xp安装成功后进入不了系统

    1.如果是用虚拟光驱,你肯定步骤是先新建的虚拟机,再安装的虚拟光驱,所以会出现这样的问题.(请先安装虚拟光驱,再新建虚拟机,再用虚拟光驱加载镜像文件,问题解决)2.如果是直接使用的镜像,那么在GHOS ...

  10. k[原创]Faster R-CNN论文翻译

    物体检测论文翻译系列: 建议从前往后看,这些论文之间具有明显的延续性和递进性. R-CNN SPP-net Fast R-CNN Faster R-CNN Faster R-CNN论文翻译   原文地 ...