牛客国庆集训派对Day3 Solution

A    Knight

留坑。

 

B    Tree

思路:两次树形DP,但是要考虑0没有逆元

可以用前缀后缀做

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 #define N 1000010
 5 #define ll long long
 6  
 7 const ll MOD = (ll)1e9 + 7;
 8  
 9  
10 int n;
11 ll dp[N], dp2[N];
12 ll prefix[N], suffix[N];
13 vector <int> G[N]; 
14  
15 void Init()
16 {
17     for (int i = 1; i <= n; ++i) dp[i] = 1, dp2[i] = 0, G[i].clear();
18 }
19  
20 void DFS(int u, int fa)
21 {
22     for (auto v : G[u])
23     {
24         if (v == fa) continue;
25         DFS(v, u);
26         dp[u] = dp[u] * (dp[v] + 1) % MOD;
27     }
28 }
29  
30 void DFS2(int u, int fa)
31 {
32     prefix[0] = 1;
33     suffix[G[u].size() + 1] = 1;
34     int len = G[u].size();
35     for (int i = 0; i < len; ++i)
36     {
37         int v = G[u][i];
38         if (v == fa) prefix[i + 1] = prefix[i];
39         else prefix[i + 1] = prefix[i] * (dp[G[u][i]] + 1) % MOD;
40     }
41     for (int i = len - 1; i >= 0; --i)
42     {
43         int v = G[u][i];
44         if (v == fa) suffix[i + 1] = suffix[i + 2];
45         else suffix[i + 1] = suffix[i + 2] * (dp[G[u][i]] + 1) % MOD;
46  
47     }
48     for (int i = 0; i < len; ++i) 
49     {
50         int v = G[u][i];
51         if (v == fa) continue; 
52         dp2[v] = prefix[i] % MOD * suffix[i + 2] % MOD * (dp2[u] + 1) % MOD; 
53     }
54     for (auto v : G[u])
55     {
56         if (v == fa) continue;
57         DFS2(v, u);
58     }
59 }
60  
61 void Run()
62 {
63     while (scanf("%d", &n) != EOF)
64     {
65         Init();
66         for (int i = 1, u, v; i < n; ++i)
67         {
68             scanf("%d%d", &u, &v);
69             G[u].push_back(v);
70             G[v].push_back(u);
71         }
72         DFS(1, 0); DFS2(1, 0);
73         for (int i = 1; i <= n; ++i) printf("%lld\n", dp[i] * (dp2[i] + 1) % MOD);
74     }
75 }
76  
77 int main()
78 {
79     #ifdef LOCAL
80         freopen("Test.in", "r", stdin);
81     #endif
82  
83     Run();
84     return 0;
85 }
View Code

 

C    Two Graphs

留坑。

 

D    Shopping

贪心即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1010
 5 
 6 int t, n, m;
 7 int arr[N], res;
 8 
 9 int main()
10 {
11     scanf("%d", &t);
12     while (t--)
13     {
14         res = 0;
15         scanf("%d%d", &n, &m);
16         for (int i = 1, b; i <= n; ++i) 
17         {
18             scanf("%d%d", arr + i, &b);
19             if (b) ++res;
20         }
21         sort(arr + 1, arr + 1 + n);
22         res = min(res, m);
23         double ans = 0;
24         for (int i = n; i >= 1; --i, --res)
25             ans += res > 0 ? arr[i] * 1.0 / 2 : arr[i];
26         printf("%.1f\n", ans);
27     }
28     return 0;
29 }
View Code

 

E    Trophies

留坑。

 

F    Palindrome

留坑。

 

G    Stones

留坑。

 

H    Travel

思路:隔板法,一条边相当于划成两个区域。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 #define ll long long
 5 #define N 100010
 6  
 7 const ll MOD = (ll)1e9 + 7;
 8  
 9 ll fac[N];
10  
11 void Init()
12 {
13     fac[0] = 1;
14     for (int i = 1; i < N; ++i) fac[i] = fac[i - 1] * i % MOD;
15 }
16  
17 ll qpow(ll base, ll n)
18 {
19     ll res = 1;
20     while (n)
21     {
22         if (n & 1) res = res * base % MOD;
23         base = base * base % MOD;
24         n >>= 1;
25     }
26     return res;
27 }
28  
29 ll C(ll n, ll m)
30 {
31     if (m > n) return 0;
32     return fac[n] * qpow(fac[m] * fac[n - m] % MOD, MOD - 2) % MOD;
33 }
34  
35 int t, n, m;
36  
37 int main()
38 {
39     Init();
40     scanf("%d", &t);
41     while (t--)
42     {
43         scanf("%d%d", &n, &m);
44         for (int i = 1, a, b; i < n; ++i) scanf("%d%d", &a, &b);
45         printf("%lld\n", C(n - 1, m - 1) * fac[m] % MOD);
46     }
47     return 0;
48 }
View Code

 

I    Metropolis

思路:将所有大都会都放到最短路去跑多源最短路,记录每个点的最短路是由哪个点扩展而来

显然,如果一个点源点i扩展到一个点j, 而点j又已经被点k扩展了,那么就没有必要扩展下去

我们在枚举每一条边,更新答案

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 200010
  5 #define ll long long
  6 #define INFLL 0x3f3f3f3f3f3f3f3f
  7 
  8 struct Edge
  9 {
 10     int to, nx; ll w;
 11     Edge() {}
 12     Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
 13 }edge[N << 1];
 14 
 15 int n, m, p;
 16 int head[N], pos;
 17 int x[N], Belong[N];
 18 ll dis[N], ans[N];
 19 
 20 void addedge(int u, int v, ll w)
 21 {
 22     edge[++pos] = Edge(v, head[u], w); head[u] = pos; 
 23 }
 24 
 25 struct node
 26 {
 27     ll w; int u, v;
 28     node() {}
 29     node(int u, int v, ll w) : u(u), v(v), w(w) {}
 30     bool operator < (const node &r) const
 31     {
 32         return w > r.w;
 33     }
 34 };
 35 
 36 priority_queue <node> q;
 37 
 38 void Init()
 39 {
 40     memset(head, -1, sizeof head);
 41     pos = 0;
 42     while (!q.empty()) q.pop();
 43     memset(Belong, 0, sizeof Belong);
 44     memset(ans, 0x3f, sizeof ans);
 45 }
 46 
 47 void Dijkstra()
 48 {
 49     while (!q.empty())
 50     {
 51         node top = q.top(); q.pop();
 52         if (Belong[top.v]) continue;
 53         Belong[top.v] = top.u;
 54         dis[top.v] = top.w; 
 55         for (int it = head[top.v]; ~it; it = edge[it].nx)
 56         {
 57             int v = edge[it].to;
 58             q.emplace(top.u, v, top.w + edge[it].w);
 59         }
 60     }
 61 }
 62 
 63 void Run()
 64 {
 65     while (scanf("%d%d%d", &n, &m, &p) != EOF) 
 66     {
 67         Init();
 68         for (int i = 1; i <= p; ++i)
 69         {
 70             scanf("%d", x + i);
 71             q.emplace(x[i], x[i], 0);
 72         }
 73         for (int i = 1, u, v, w; i <= m; ++i)
 74         {
 75             scanf("%d%d%d", &u, &v, &w);
 76             addedge(u, v, w);
 77             addedge(v, u, w);
 78         }
 79         Dijkstra(); 
 80         for (int u = 1; u <= n; ++u)
 81         {
 82             for (int it = head[u]; ~it; it = edge[it].nx)
 83             {
 84                 int v = edge[it].to;
 85                 ll w = edge[it].w;
 86                 if (Belong[u] == Belong[v]) continue;
 87                 ans[Belong[u]] = min(ans[Belong[u]], dis[u] + dis[v] + w);
 88                 ans[Belong[v]] = min(ans[Belong[v]], dis[u] + dis[v] + w); 
 89             }
 90         }
 91         for (int i = 1; i <= p; ++i) printf("%lld%c", ans[x[i]], " \n"[i == p]);
 92     }
 93 }
 94 
 95 int main()
 96 {
 97     #ifdef LOCAL
 98         freopen("Test.in", "r", stdin);
 99     #endif
100 
101     Run();
102     return 0;
103 }
View Code

 

 

J    Graph Coloring I

思路:对于一张图,如果没有奇圈,那么肯定可以用两种颜色进行染色,那么肯定有解

只要去找奇圈即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 300010
 5 
 6 int n, m;
 7 vector <int> G[N], ans;
 8 int deep[N], fa[N];
 9 bool flag;
10 
11 void DFS(int u)
12 {
13     if (flag) return; 
14     for (auto v : G[u])
15     {
16         if (flag) return;
17         if (v == fa[u]) continue;
18         if (fa[v] != -1 && !flag)
19         {
20             if ((deep[u] - deep[v]) % 2 == 0)
21             {
22                 ans.push_back(u);
23                 while (u != v)
24                 {
25                     u = fa[u];
26                     ans.push_back(u);
27                 }
28                 flag = true;
29                 return;
30             }
31         }
32         else
33         {
34             fa[v] = u;
35             deep[v] = deep[u] + 1;
36             DFS(v);     
37         }
38     }
39 }
40 
41 void Init()
42 {
43     for (int i = 1; i <= n; ++i) G[i].clear(); 
44     ans.clear();
45     memset(fa, -1, sizeof fa); 
46     deep[1] = 0;     
47     flag = false;
48 }
49 
50 int main()
51 {
52     while (scanf("%d%d", &n, &m) != EOF)
53     {
54         Init();
55         for (int i = 1, u, v; i <= m; ++i) 
56         {
57             scanf("%d%d", &u, &v);
58             G[u].push_back(v);
59             G[v].push_back(u);
60         }
61         DFS(1);
62         if (flag)
63         {
64             printf("%d\n", (int)ans.size());
65             for (int i = 0, len = ans.size(); i < len; ++i) printf("%d%c", ans[i], " \n"[i == len - 1]);
66         }
67         else
68         {
69             puts("0");
70             for (int i = 1; i <= n; ++i) printf("%d%c", deep[i] & 1, " \n"[i == n]);
71         }
72     }
73     return 0;
74 }
View Code

 

K    Graph Coloring II

留坑。

posted @ 2018-10-03 19:15  Dup4  阅读(223)  评论(0编辑  收藏  举报