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. abstract (C# Reference)

    https://msdn.microsoft.com/en-us/library/sf985hc5.aspx The abstract modifier indicates that the thin ...

  2. activiti安装-------安装插件

    对上面的放大

  3. maven的pom.xml文件错误

    来自:http://www.cnblogs.com/shihujiang/p/3492864.html

  4. [Swift通天遁地]五、高级扩展-(13)图片资源本地化设置:根据不同的语言环境显示不同语言版本图片

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. SpringBoot入门之HelloWorld

    1.SpringBoot简介 百度百科:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而 ...

  6. go 简单路由实现

    一.golang 路由实现的简单思路 1.http启动后,请求路径时走统一的入口函数 1.通过统一函数入口,获取request 的url路径 2.通过对url的路径分析,确定具体执行什么函数 二.统一 ...

  7. 最少拦截系统------LCS--------动态规划

    这是一道极好的题,会了这个应该说 最长递增子序列什么的  就有了另外一种思路了 下面附上代码---应该仔细的看一下  那个  if判断 #include<stdio.h> #include ...

  8. Intent的调用

    //Intent  intent=new Intent();//intent.setClass(MainActivity.this, GPSService.class);//以上二条可以合并成如下一条 ...

  9. win7 硬盘安装suse双系统启动顺序更改

    使用win7硬盘安装suse双系统之后,首先面临的问题是,PC默认启动的系统更改的问题,有些人可能想默认启动是win7,只有在使用linux的时候在去选择suse系统,这里我告诉大家更改的办法: 首先 ...

  10. ORA-02068,ORA-03135错误解决方法

    今天查看了下ERP DB服务器 alter_<SID>.log日志,发现有个错误 Sat Sep 14 14:49:42 CST 2013 Error 2068 trapped in 2P ...