• bupt summer training for 16 #6 ——图论


    https://vjudge.net/contest/174020

    A.100条双向边,每个点最少连2个边

    所以最多100个点,点的标号需要离散化

    然后要求恰好经过n条路径

    快速幂,乘法过程就是floyed就行了

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 1010;
     8 
     9 int n, m, s, t, b, c[1001];
    10 
    11 struct matrix {
    12     int c[101][101];
    13     matrix() {
    14         memset(c, 0x3f, sizeof c);
    15     }
    16     void add(int u, int v, int w) {
    17         c[u][v] = c[v][u] = w;
    18     }
    19     matrix operator * (const matrix &a) const {
    20         matrix b;
    21         for(int k = 1;k <= n;k ++)
    22             for(int i = 1;i <= n;i ++)
    23                 for(int j = 1;j <= n;j ++)
    24                     b.c[i][j] = min(b.c[i][j], c[i][k] + a.c[k][j]);
    25         return b;
    26     }
    27     matrix operator ^ (int &k) {
    28         matrix b = *this;
    29         for(k --;k > 0;k >>= 1, *this = (*this) * (*this))
    30             if(k & 1) b = b * (*this);
    31         return b;
    32     }
    33 };
    34 
    35 int main() {
    36     matrix g;
    37     int u, v, w;
    38     scanf("%d %d %d %d", &n, &m, &s, &t);
    39     while(m --) {
    40         scanf("%d %d %d", &w, &u, &v);
    41         if(!c[u]) c[u] = ++ b;
    42         if(!c[v]) c[v] = ++ b;
    43         g.add(c[u], c[v], w);
    44     }
    45     swap(b, n);
    46     printf("%d", (g ^ b).c[c[s]][c[t]]);
    47     return 0;
    48 }
    View Code

    B.

    C.非常裸的生成树计数问题

    其实谁是最高管理层并没什么卵用

    想当然理解了读入,垃圾题目有重边

    注意有重边,整数行列式计算可以拿来当板子了

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 1010;
     8 
     9 int n, m, s, t, b, c[1001];
    10 
    11 struct matrix {
    12     int c[101][101];
    13     matrix() {
    14         memset(c, 0x3f, sizeof c);
    15     }
    16     matrix(int x) {
    17         memset(c, 0, sizeof c);
    18         for(int i = 1;i <= n;i ++)
    19             c[i][i] = 1;
    20     }
    21     void add(int u, int v, int w) {
    22         c[u][v] = c[v][u] = w;
    23     }
    24     matrix operator * (const matrix &a) const {
    25         matrix b;
    26         for(int k = 1;k <= n;k ++)
    27             for(int i = 1;i <= n;i ++)
    28                 for(int j = 1;j <= n;j ++)
    29                     b.c[i][j] = min(b.c[i][j], c[i][k] + a.c[k][j]);
    30         return b;
    31     }
    32     matrix operator ^ (int &k) {
    33         matrix b = *this;
    34         for(k --;k > 0;k >>= 1, *this = (*this) * (*this))
    35             if(k & 1) b = b * (*this);
    36         return b;
    37     }
    38 };
    39 
    40 int main() {
    41     matrix g;
    42     int u, v, w;
    43     scanf("%d %d %d %d", &n, &m, &s, &t);
    44     while(m --) {
    45         scanf("%d %d %d", &w, &u, &v);
    46         if(!c[u]) c[u] = ++ b;
    47         if(!c[v]) c[v] = ++ b;
    48         g.add(c[u], c[v], w);
    49     }
    50     swap(b, n);
    51     printf("%d", (g ^ b).c[c[s]][c[t]]);
    52     return 0;
    53 }
    View Code

    D.

    E.高中做过的网络流模型

    每行被隔开的算一块,st向这些块连边流量为1

    因为这样一个块里最多放一个棋子

    每列被隔开的算一块,这些块向en连边流量为1,道理同上

    行块和列快相遇出可以放旗子,那么它们连一条边流量为1

    因为只有一个位置

    求个最大流...这样一说直接二分图上匈牙利就可以了...

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 50010, maxm = 1000010, inf = 0x3f3f3f3f;
     8 
     9 int s, t, len = 1, g[maxn];
    10 
    11 struct edge {
    12     int to, cap, next;
    13 }e[maxm];
    14 
    15 int p[maxn], q[maxn], d[maxn];
    16 
    17 void add(int u, int v, int w) {
    18     e[++ len] = (edge){v, w, g[u]}, g[u] = len;
    19     e[++ len] = (edge){u, 0, g[v]}, g[v] = len;
    20 }
    21 
    22 bool bfs() {
    23     int l = 1, r = 1, x, i;
    24     memset(d, 0, sizeof d);
    25     d[s] = 1, q[1] = s;
    26     while(l <= r) {
    27         x = q[l ++];
    28         for(i = g[x];i;i = e[i].next)
    29             if(e[i].cap && !d[e[i].to])
    30                 d[e[i].to] = d[x] + 1, q[++ r] = e[i].to;
    31     }
    32     return d[t];
    33 }
    34 
    35 int dfs(int x, int y) {
    36     if(x == t || y == 0) return y;
    37     int flow = 0;
    38     for(int &i = p[x];i;i = e[i].next) {
    39         if(!e[i].cap  || d[e[i].to] != d[x] + 1) continue;
    40         int f = dfs(e[i].to, min(y, e[i].cap));
    41         flow += f, y -= f;
    42         e[i].cap -= f, e[i ^ 1].cap += f;
    43         if(!y) break;
    44     }
    45     return flow;
    46 }
    47 
    48 int dinic() {
    49     int maxflow = 0;
    50     while(bfs()) {
    51         memcpy(p, g, sizeof g);
    52         maxflow += dfs(s, inf);
    53     }
    54     return maxflow;
    55 }
    56 
    57 int n, m, cnt;
    58 
    59 char str[110][110];
    60 
    61 int mmp[110][110];
    62 
    63 int main() {
    64     t = 10001;
    65     while(~scanf("%d", &n)) {
    66         m = 0;
    67         memset(g, 0, sizeof g);
    68         for(int  i = 1;i <= n;i ++)
    69             scanf("%s", str[i] + 1);
    70         for(int i = 1;i <= n;i ++) {
    71             for(int j = 1;j <= n;j ++) {
    72                 if(str[i][j] == 'X') mmp[i][j] = -1;
    73                 else {
    74                     if(j == 1 || str[i][j - 1] == 'X') m ++, add(s, m, 1);
    75                     mmp[i][j] = m;
    76                 }
    77             }
    78         }
    79         for(int j = 1;j <= n;j ++)
    80             for(int i = 1;i <= n;i ++) {
    81                 if(str[i][j] != 'X') {
    82                     if(i == 1 || str[i - 1][j] == 'X') m ++, add(m, t, 1);
    83                     add(mmp[i][j], m, inf);
    84                 }
    85             }
    86         printf("%d
    ", dinic());
    87     }
    88 }
    View Code

    F.裸的最短路,当然你要看到这是

    单向边!!!

     1 #include <queue>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 const int maxn = 1010;
     9 
    10 queue <int> q;
    11 
    12 int n, m, k, t, d[maxn], vis[maxn];
    13 
    14 vector <pair<int, int> > e[maxn];
    15 
    16 int main(){
    17     while(~scanf("%d %d %d", &n, &m, &k)) {
    18         for(int i = 1;i <= n;i ++) d[i] = 0x3f3f3f3f, e[i].clear();
    19         for(int u, v, w, i = 1;i <= m;i ++) {
    20             scanf("%d %d %d", &u, &v, &w);
    21             e[u].push_back(make_pair(v, w));
    22             //e[v].push_back(make_pair(u, w));
    23         }
    24         scanf("%d", &t);
    25         for(int j, i = 1;i <= t;i ++)
    26             scanf("%d", &j), d[j] = 0, q.push(j);
    27         while(!q.empty()) {
    28             int u = q.front();
    29             q.pop(), vis[u] = 0;
    30             for(int i = 0;i < e[u].size();i ++) {
    31                 if(d[e[u][i].first] > d[u] + e[u][i].second) {
    32                     d[e[u][i].first] = d[u] + e[u][i].second;
    33                     if(!vis[e[u][i].first]) vis[e[u][i].first] = 1, q.push(e[u][i].first);
    34                 }
    35             }
    36         }
    37         printf("%d
    ", d[k] == 0x3f3f3f3f ? -1 : d[k]);
    38     }
    39     return 0;
    40 }
    View Code

    G.裸MST,稠密图没有卡 Kruskal,良心!

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 struct edge {
     7     int u, v, w;
     8     bool operator < (const edge &a) const {
     9         return w < a.w;
    10     }
    11 }e[10010];
    12 
    13 int n, f[110];
    14 
    15 int find_(int x) {
    16     if(f[x] != x) return f[x] = find_(f[x]);
    17     return x;
    18 }
    19 
    20 int main() {
    21     while(~scanf("%d", &n)) {
    22         int m = 0, ans = 0;
    23         for(int k, i = 1;i <= n;i ++) {
    24             f[i] = i;
    25             for(int j = 1;j <= i;j ++) scanf("%d", &k);
    26             for(int j = i + 1;j <= n;j ++) scanf("%d", &k), e[++ m] = (edge){i, j, k};
    27         }
    28         sort(e + 1, e + m + 1);
    29         for(int u, v, i = 1, j = 1;j < n;i ++) {
    30             u = find_(e[i].u), v = find_(e[i].v);
    31             if(u == v) continue;
    32             f[v] = u, j ++, ans += e[i].w;
    33         }
    34         printf("%d
    ", ans);
    35     }
    36     return 0;
    37 }
    View Code

    H.

    I.经典网络流模型

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 110, maxm = 50010, inf = 0x3f3f3f3f;
     8 
     9 int s, t, len = 1, g[maxn];
    10 
    11 struct edge {
    12     int to, cap, next;
    13 }e[maxm];
    14 
    15 int p[maxn], q[maxn], d[maxn];
    16 
    17 void add(int u, int v, int w) {
    18     e[++ len] = (edge){v, w, g[u]}, g[u] = len;
    19     e[++ len] = (edge){u, 0, g[v]}, g[v] = len;
    20 }
    21 
    22 bool bfs() {
    23     int l = 1, r = 1, x, i;
    24     memset(d, 0, sizeof d);
    25     d[s] = 1, q[1] = s;
    26     while(l <= r) {
    27         x = q[l ++];
    28         for(i = g[x];i;i = e[i].next)
    29             if(e[i].cap && !d[e[i].to])
    30                 d[e[i].to] = d[x] + 1, q[++ r] = e[i].to;
    31     }
    32     return d[t];
    33 }
    34 
    35 int dfs(int x, int y) {
    36     if(x == t || y == 0) return y;
    37     int flow = 0;
    38     for(int &i = p[x];i;i = e[i].next) {
    39         if(!e[i].cap  || d[e[i].to] != d[x] + 1) continue;
    40         int f = dfs(e[i].to, min(y, e[i].cap));
    41         flow += f, y -= f;
    42         e[i].cap -= f, e[i ^ 1].cap += f;
    43         if(!y) break;
    44     }
    45     return flow;
    46 }
    47 
    48 int dinic() {
    49     int maxflow = 0;
    50     while(bfs()) {
    51         memcpy(p, g, sizeof g);
    52         maxflow += dfs(s, inf);
    53     }
    54     return maxflow;
    55 }
    56 
    57 int Case, n, m, sum;
    58 
    59 int main() {
    60     scanf("%d", &Case);
    61     for(int tt = 1;tt <= Case;tt ++) {
    62         sum = 0, len = 1;
    63         memset(g, 0, sizeof g);
    64         printf("Case #%d: ", tt);
    65         scanf("%d %d", &n, &m), t = n + m + 1;
    66         for(int j, i = 1;i <= n;i ++)
    67             scanf("%d", &j), add(s, i, j), sum += j;
    68         for(int j, i = 1;i <= m;i ++)
    69             scanf("%d", &j), add(n + i, t, j);
    70         for(int k, j, i = 1;i <= n;i ++) {
    71             scanf("%d", &k);
    72             while(k --) {
    73                 scanf("%d", &j);
    74                 add(i, n + j + 1, inf);
    75             }
    76         }
    77         for(int k, i = 1;i <= m;i ++)
    78             for(int j = 1;j <= m;j ++) {
    79                 scanf("%d", &k);
    80                 if(k) add(n + i, n + j, inf);
    81             }
    82         printf("%d
    ", sum - dinic());
    83     }
    84     return 0;
    85 }
    View Code

    J.随便做的傻逼题,我写的算麻烦的

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 int n, a[110];
     7 
     8 int main() {
     9     scanf("%d", &n);
    10     for(int i = 1;i <= n;i ++)
    11         scanf("%d", &a[i]);
    12     int l = 1, r = n;
    13     while(!a[l] && l <= n) l ++;
    14     while(!a[r] && r >= 1) r --;
    15     if(l > r) puts("0");
    16     else {
    17         int ans = 1, last = 1;
    18         for(int i = l + 1;i <= r;i ++) {
    19             if(a[i]) {
    20                 ans ++;
    21                 if(last != 1) last = 1;
    22             }
    23             else {
    24                 if(last != 0) {
    25                     if(i < r && !a[i + 1]) last = 0;
    26                     else ans ++;
    27                 }
    28             }
    29         }
    30         printf("%d
    ", ans);
    31     }
    32     return 0;
    33 }
    View Code
  • 相关阅读:
    结对编程队友个人项目分析
    Android入门3:从Toolbar到Material Design
    Qt串口通信
    AVT Vimba与OpenCV环境配置
    Git远程使用技巧
    Android入门2:从GridView控件使用到自定义Adapter
    Android入门1:使用VideoView和MediController播放视频
    kafka+spark streaming+redis学习
    kafka学习笔记
    安卓获取服务器返回的图片资源路径并下载图片
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/7253875.html
Copyright © 2020-2023  润新知