zoukankan      html  css  js  c++  java
  • 10.05-10.11

    //本周依旧做一下图算法的题目,尽量少用algorithm里的函数,自己写熟悉熟悉。

    1.The Unique MST

    解析:该题为次小生成树问题。

    次小生成树的求解过程:

    1、找到最小生成树,值为mst

    2、最小生成树种的点:找到每一个点到其它点的路径上的最大边权值 dp[i][j]表示i到j路径上的最大边权值

    3、加一条不在最小生成树上的边。比如i - k,同时删除在最小生成树上i -> k路径上最大的一个边权值dp[i][k]; 这样会得到 new_mst,在这些new_mst中找一个最小的,就是次小生成树的值

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <string>
      6 #include <cstring>
      7 
      8 using namespace std;
      9 
     10 #define INF 1000000007
     11 #define MAXN 105
     12 #define MAX(a, b) (a > b ? a : b)
     13 #define MIN(a, b) (a < b ? a : b)
     14 
     15 struct Edge
     16 {
     17     int v;
     18     int next;
     19 }edge[100010];
     20 
     21 int t, n, m, T;
     22 int d[MAXN], vis[MAXN], pre[MAXN], head[MAXN];
     23 int g[MAXN][MAXN], dp[MAXN][MAXN], in_mst[MAXN][MAXN];
     24 
     25 void init()
     26 {
     27     t = 0;
     28     for (int i = 0; i <= n; ++i)
     29         for (int j = 0; j <= n; ++j)
     30             g[i][j] = (i == j ? 0 : INF);
     31     memset(head, -1, sizeof(head));
     32     memset(in_mst, 0, sizeof(in_mst));
     33     memset(dp, 0, sizeof(dp));
     34 }
     35 
     36 void addEdge(int u, int v)
     37 {
     38     edge[t].v = v;
     39     edge[t].next = head[u];
     40     head[u] = t++;
     41 }
     42 
     43 int prim()
     44 {
     45     int ans = 0;
     46 
     47     for (int i = 1; i <= n; ++i)
     48         d[i] = INF, pre[i] = 0, vis[i] = 0;
     49     pre[1] = 0, d[1] = 0;
     50     for (int i = 1; i <= n; ++i)
     51     {
     52         int min_cost = INF, idx = 0;
     53         for (int j = 1; j <= n; ++j)
     54             if (!vis[j] && min_cost > d[j])
     55                 min_cost = d[idx = j];
     56         vis[idx] = 1;
     57         ans += min_cost;
     58         for (int j = 1; j <= n; ++j)
     59             if (!vis[j] && d[j] > g[idx][j])
     60                 d[j] = g[idx][j], pre[j] = idx;
     61     }
     62     for (int i = 1; i <= n; ++i)
     63         if (pre[i]) in_mst[pre[i]][i] = in_mst[i][pre[i]] = 1;
     64     for (int i = 1; i <= n; ++i)
     65         if (pre[i])
     66             addEdge(pre[i], i), addEdge(i, pre[i]);
     67 
     68     return ans;
     69 }
     70 
     71 void dfs(int u, int v, int w)
     72 {
     73     vis[v] = 1;
     74     dp[u][v] = w;
     75     for (int e = head[v]; e != -1; e = edge[e].next)
     76         if (!vis[edge[e].v])
     77             dfs(u, edge[e].v, max(w, g[v][edge[e].v]));
     78 }
     79 
     80 int main()
     81 {
     82     scanf("%d", &T);
     83     while (T--)
     84     {
     85         scanf("%d%d", &n, &m);
     86         init();
     87         int u, v, w;
     88         while (m--)
     89         {
     90             scanf("%d%d%d", &u, &v, &w);
     91             g[u][v] = g[v][u] = w;
     92         }
     93         int mst = prim();
     94         int ans = INF;
     95         for (int i = 1; i <= n; ++i)
     96         {
     97             memset(vis, 0, sizeof(vis));
     98             dfs(i, i, 0);
     99         }
    100         for (int i = 1; i <= n; ++i)
    101             for (int j = i+1; j <= n; ++j)
    102                 if (!in_mst[i][j] && g[i][j] != INF)
    103                     ans = min(ans, mst-dp[i][j]+g[i][j]);
    104         if (ans == mst) puts("Not Unique!");
    105         else printf("%d
    ", mst);
    106     }
    107 
    108     return 0;
    109 }
    View Code

     2.Sorting It All Out

     1 //添加一条边就要判断一下,最后判断出Sorted sequence cannot be determined.
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <string>
     7 #include <cstring>
     8 
     9 using namespace std;
    10 
    11 #define INF 1000000007
    12 #define MAXN 30
    13 #define MAX(a, b) (a > b ? a : b)
    14 #define MIN(a, b) (a < b ? a : b)
    15 
    16 int n, m, pos1, pos2, pos3;
    17 char ch[5];
    18 int in[MAXN], ans[MAXN];
    19 int g[MAXN][MAXN];
    20 
    21 int work()
    22 {
    23     int temp[MAXN], total = 0, idx = -1, flag = 0;
    24     for (int i = 0; i < n; ++i)
    25         temp[i] = in[i];
    26     for (int i = 0; i < n; ++i)
    27     {
    28         int cnt = 0;
    29         for (int j = 0; j < n; ++j)
    30             if (temp[j] == 0) idx = j, cnt++;
    31         if (cnt == 0) return 0;
    32         if (cnt > 1) flag = 1;
    33         temp[idx]--; ans[total++] = idx;
    34         for (int j = 0; j < n; ++j)
    35             if (g[idx][j]) temp[j]--;
    36     }
    37     if (flag) return -1;
    38     return 1;
    39 }
    40 
    41 int main()
    42 {
    43     while (~scanf("%d%d", &n, &m) && n+m!=0)
    44     {
    45         int flag = 0;
    46         memset(g, 0, sizeof(g));
    47         memset(in, 0, sizeof(in));
    48         for (int i = 0; i < m; ++i)
    49         {
    50             scanf("%s", ch);
    51             if (flag) continue;
    52             g[ch[0]-'A'][ch[2]-'A'] = 1;
    53             in[ch[2]-'A']++;
    54             int ret = work();
    55             if (ret == 0)
    56             {
    57                 printf("Inconsistency found after %d relations.
    ", i + 1);
    58                 flag = 1;
    59             }
    60             else if (ret == 1)
    61             {
    62                 printf("Sorted sequence determined after %d relations: ", i + 1);
    63                 for (int j = 0; j < n; ++j) printf("%c", ans[j]+'A');
    64                 puts(".");
    65                 flag = 1;
    66             }
    67         }
    68         if (!flag) puts("Sorted sequence cannot be determined.");
    69     }
    70 
    71     return 0;
    72 }
    View Code

     3.The Cow Lexicon

     1 //先求出g[i][j]两点之间最少删除字符,然后DP,感觉测试数据应该比较弱,因为我1A了。。。
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <string>
     7 #include <cstring>
     8 
     9 using namespace std;
    10 
    11 #define INF 1000000007
    12 #define MAXN 310
    13 #define MAX(a, b) (a > b ? a : b)
    14 #define MIN(a, b) (a < b ? a : b)
    15 
    16 char msg[MAXN];
    17 int W, L;
    18 int dis[MAXN];
    19 char ch[610][MAXN];
    20 int g[MAXN][MAXN];
    21 
    22 int main()
    23 {
    24     for (int i = 0; i < MAXN; ++i)
    25         for (int j = i; j < MAXN; ++j)
    26             g[i][j] = j-i+1;
    27     scanf("%d%d", &W, &L);
    28     scanf("%s", msg);
    29     for (int i = 0; i < W; ++i) scanf("%s", ch[i]);
    30     for (int i = 0; i < W; ++i)
    31     {
    32         for (int j = 0; j < L; ++j)
    33         {
    34             if (ch[i][0] == msg[j])
    35             {
    36                 int x = j, y = 0, cnt = 0;
    37                 while (x < L && y < strlen(ch[i]))
    38                 {
    39                     if (msg[x] == ch[i][y]) x++, y++;
    40                     else cnt++, x++;
    41                 }
    42                 if (y == strlen(ch[i]))
    43                     g[j][x-1] = min(cnt, g[j][x-1]);
    44             }
    45         }
    46     }
    47     for (int i = 0; i < MAXN; ++i) dis[i] = i+1;
    48     for (int i = 0; i < L; ++i)
    49     {
    50         int pre = i == 0 ? 0 : dis[i-1];
    51         for (int j = i; j < L; ++j)
    52             dis[j] = min(pre+g[i][j], dis[j]);
    53     }
    54     printf("%d
    ", dis[L-1]);
    55 
    56     return 0;
    57 }
    View Code

     4.Word Pattern

     1 //水题
     2 class Solution {
     3 public:
     4     bool wordPattern(string pattern, string str) {
     5         vector<string> v;
     6         v.clear();
     7         string add = "";
     8         for (int i = 0; i < str.length(); ++i)
     9         {
    10             if (str[i] == ' ')
    11                 v.push_back(add), add = "";
    12             else add += str[i];
    13         }
    14         if (add != "")v.push_back(add);
    15         if (pattern.length() != v.size()) return false;
    16         for (int i = 0; i < pattern.length(); ++i)
    17         {
    18             for (int j = i+1; j < pattern.length(); ++j)
    19             {
    20                 if (pattern[i] == pattern[j] && v[i] != v[j]) return false;
    21                 if (pattern[i] != pattern[j] && v[i] == v[j]) return false;        
    22             }
    23         }
    24         return true;
    25     }
    26 };
    View Code

     //关于图匹配的一些算法还是有点麻烦==。边学边做。。。

    5.Strategic Game

     1 //最小顶点覆盖
     2 #include <iostream>
     3 #include <string>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <vector>
     9 #include <set>
    10 #include <map>
    11 #include <fstream>
    12 #include <cstdlib>
    13 #define NDEBUG
    14 #include <cassert>
    15 
    16 using namespace std;
    17 
    18 #define INF 1000000007
    19 #define MIN(a, b) (a > b ? b : a)
    20 #define MAX(a, b) (a > b ? a : b)
    21 #define MAXN 2005
    22 
    23 struct Edge
    24 {
    25     int v;
    26     int next;    
    27 };
    28 
    29 int cnt, n;
    30 int vis[MAXN], link[MAXN], head[MAXN];
    31 Edge edge[MAXN*MAXN];
    32 
    33 void init()
    34 {
    35     cnt = 0;
    36     memset(head, -1, sizeof(head));
    37 }
    38 
    39 void addEdge(int u, int v)
    40 {
    41     edge[cnt].v = v;
    42     edge[cnt].next = head[u];
    43     head[u] = cnt++;    
    44 }
    45 
    46 int dfs(int u)
    47 {
    48     for (int e = head[u]; ~e; e = edge[e].next)
    49     {
    50         int v = edge[e].v;
    51         if (!vis[v])
    52         {
    53             vis[v] = 1;
    54             if (link[v] == -1 || dfs(link[v]))
    55             {
    56                 link[v] = u;
    57                 return 1;
    58             }
    59         }
    60     }
    61     return 0;
    62 }
    63 
    64 int match()
    65 {
    66     int ans = 0;
    67     memset(link, -1, sizeof(link));
    68     for (int i = 0; i < n; ++i)
    69     {
    70         memset(vis, 0, sizeof(vis));
    71         if (dfs(i)) ans++;
    72     }
    73     return ans;
    74 }
    75 
    76 int main()
    77 {
    78     while (~scanf("%d", &n))
    79     {
    80         init();
    81         for (int i = 0; i < n; ++i)
    82         {
    83             int u, v, k;
    84             scanf("%d:(%d)", &u, &k);
    85             while (k--)
    86             {
    87                 scanf("%d", &v);
    88                 addEdge(u, v);
    89                 addEdge(v, u);
    90             }
    91         }
    92         printf("%d
    ", match()/2);
    93     }    
    94     
    95     return 0;
    96 }
    View Code

     6.Machine Schedule

     1 //匈牙利算法,0的时候无需重启,所以处理的时候是从1开始的,而不是从0
     2 #include <iostream>
     3 #include <string>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <vector>
     9 #include <set>
    10 #include <map>
    11 #include <fstream>
    12 #include <cstdlib>
    13 #define NDEBUG
    14 #include <cassert>
    15 
    16 using namespace std;
    17 
    18 #define INF 1000000007
    19 #define MIN(a, b) (a > b ? b : a)
    20 #define MAX(a, b) (a > b ? a : b)
    21 #define MAXN 105
    22 
    23 int n, m, k;
    24 int link[MAXN], vis[MAXN];
    25 int edge[MAXN][MAXN];
    26 
    27 void init()
    28 {
    29     memset(edge, 0, sizeof(edge));    
    30     memset(link, -1, sizeof(link));
    31 }
    32 
    33 int dfs(int u)
    34 {
    35     for (int j = 1; j < m; ++j)
    36     {
    37         if (edge[u][j] && !vis[j])
    38         {
    39             vis[j] = 1;
    40             if (link[j] == -1 || dfs(link[j]))
    41             {
    42                 link[j] = u;
    43                 return 1;
    44             }
    45         }
    46     }
    47     return 0;    
    48 }
    49 
    50 int match()
    51 {
    52     int ans = 0;
    53     for (int i = 1; i < n; ++i)
    54     {
    55         memset(vis, 0, sizeof(vis));
    56         ans += dfs(i);
    57     }
    58     return ans;
    59 }
    60 
    61 int main()
    62 {
    63     while (~scanf("%d", &n) && n)
    64     {
    65         init();
    66         scanf("%d%d", &m, &k);
    67         int j, x, y;
    68         for (int i = 0; i < k; ++i)
    69         {
    70             scanf("%d%d%d", &j, &x, &y);
    71             edge[x][y] = 1;
    72         }
    73         printf("%d
    ", match());
    74     }    
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    为什么转速环经过pi调节后输出的是电流?
    如何将mysql、php、nginx设置为开机自启动
    rm-rf /*
    2020/4/23-linux中的定时任务详解
    2020/4/20 一键部署服务
    2020/4/20-ansible一键部署nfs
    2020/4/20-backup之rsync
    2020/4/19-linux中/etc/hosts
    2020/4/18-linux中的selinux
    2020/4/18-linux中的iptables
  • 原文地址:https://www.cnblogs.com/JustForCS/p/4855395.html
Copyright © 2011-2022 走看看