2018年暑假第四次周赛-图论部分题解
2018年暑假第四次周賽-圖論部分題解
A。信我啊,這是簽到題
這題是簽到題
數據出鍋,多組后來補的,后來直接刪除了一整個文本。純屬意外。
出簽到題難啊,本意是一道題教會17一個模型的。說沒學過不該出的是沒好好看題目的第四行。
你發現當圖所有的點和與這個點直接相連(由邊直接連接)的點的個數為偶數的時候,你被錘的概率降低了一點點點點點
這句話就是無向圖歐拉回路判斷定理。不懂百度,解法都丟題目上了。所以只要判斷是否所有點的度是偶數,在并查集維護聯通即可。
幾個定理自覺記一下筆記。圖是否聯通是歐拉回路必備的坑點。
下面幾句話自覺記筆記。
如果圖G中的一個路徑包括每個邊恰好一次,則該路徑稱為歐拉路徑(Euler path)。
回路是一個點出發也要回到那個點,通路不需要回到起點。同樣都要經過所有邊。
證明自己百度或者翻《離散數學》
擴展:歐拉回路可以找路徑。算法自己找
#include <bits/stdc++.h>using namespace std; const int MAXN = 1e5 + 10;int n, m, pre[MAXN], deg[MAXN];void init() {for(int i = 1; i <= n; i++ ) {pre[i] = i;} }int findx(int x) {return pre[x] == x ? x : pre[x] = findx(pre[x]); }void join(int x, int y) {int fx = findx(x), fy = findx(y);if(fx != fy) {pre[fx] = fy;} }bool same(int x, int y) {return findx(x) == findx(y); }int main() { // freopen("2.in", "r", stdin); // freopen("2.out", "w", stdout);int u, v;while(~scanf("%d %d", &n, &m)) {init();memset(deg, 0, sizeof(deg));for(int i = 1; i <= m; i++ ) {scanf("%d %d", &u, &v);join(u, v);deg[u]++;deg[v]++;}bool ok = 1;int cnt = 0;for(int i = 1; i <= n; i++) {if(pre[i] == i) {cnt++;}if(deg[i] % 2 != 0) {ok = 0;break;}}if(ok && cnt == 1) {puts("yes");} else {puts("no");}}return 0; }
E。【C_W_L】的預言
表面數論,其實是圖論題。
\[ gcd(a_i,a_j) * gcd(a_i+1, a_j+1)≠1 \]
求一個最大集合滿足上式。如果 \(a_i\) , \(a_j\) 符合上式。那么我們連一條邊,題意就是要我們就要求該圖的最大團。(一個圖的點集合任意兩個點之間都有邊叫團)最大團等于它補圖的最大獨立集。
如果 \(a_i\), \(a_j\) 符合上式。那么我們連一條邊
那么 \(a_i\), \(a_j\) 同奇,同偶的時候必定有邊。那么補圖一定沒邊。
所以它的補圖是一個二分圖。我們求它的最大獨立集合即可。
二分圖最大獨立集,匈牙利,網絡流隨便來一個。
#include <bits/stdc++.h>using namespace std; const int MAXN = 555; typedef long long LL;int n, m, first[MAXN], sign;int links[MAXN], vis[MAXN];LL a[MAXN];struct Edge {int to, w, next; } edge[MAXN * MAXN];void init() {memset(first, -1, sizeof(first));sign = 0; }void add_edge(int u, int v, int w) {edge[sign].to = v;edge[sign].w = w;edge[sign].next = first[u];first[u] = sign++; }int dfs(int x) {for(int i = first[x]; ~i; i = edge[i].next) {int to = edge[i].to;if(!vis[to]) {vis[to] = 1;if(!links[to] || dfs(links[to])) {links[to] = x;return 1;}}}return 0; }int main() {while(~scanf("%d", &n)) {init();for(int i = 1; i <= n; i++ ) {scanf("%lld", &a[i]);}for(int i = 1; i <= n; i++ ) {for(int j = 1; j <= n; j++ ) {if(__gcd(a[i], a[j]) == 1 && __gcd(a[i] + 1, a[j] + 1) == 1) {add_edge(i, j, 1);}}}int ans = n;for(int i = 1; i <= n; i++ ) {if(a[i] & 1) {memset(vis, 0, sizeof(vis));ans -= dfs(i);}}printf("%d\n", ans);}return 0; }轉載于:https://www.cnblogs.com/Q1143316492/p/9502783.html
總結
以上是生活随笔為你收集整理的2018年暑假第四次周赛-图论部分题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SHA1加密工具
- 下一篇: Could not get lock /