怎么去接网站来做百度竞价推广自己可以做吗
【题目链接】
洛谷 P1330 封锁阳光大学
【题目考点】
1. 图论:二分图判定
【解题思路】
放河蟹可以抽象为选择顶点。
“当两只河蟹封锁了相邻的两个点时,他们会发生冲突”,也就是说不能选择一条边连接的两个顶点。
河蟹准备封锁所有道路,也就是说每条边两端的顶点至少有一个是被选择的顶点。不存在某条边两端都是未选择顶点。
对于一个图的连通分量,所有选择的顶点构成一个集合,未选择的顶点构成一个集合。图中每条边都连接了一个已选择顶点和未选择顶点,显然该图是二分图。
对每个连通分量进行二分图染色,染色的同时统计每个颜色顶点集合的顶点数量。染色后得到两种颜色的顶点集合。由于要选择最少的顶点,那么看哪一个集合的顶点数量更少,就选择哪个集合中的所有顶点。
将每个连通分量中顶点数更少的集合的顶点数加和,即为该题结果。如果某个连通分量在进行二分图判定后发现并不是二分图,那么输出Impossible。
【题解代码】
解法1:二分图判定
- 写法1:深搜二分染色
#include<bits/stdc++.h>
using namespace std;
#define N 10005
int n, m, color[N], ct[3], ans;//ct[1]、ct[2]颜色1的数量和颜色2的数量
vector<int> edge[N];
bool dfs(int u)
{for(int v : edge[u]){if(color[v] == 0){color[v] = 3-color[u];ct[color[v]]++;if(!dfs(v))return false;}else if(color[v] == color[u])return false;}return true;
}
int main()
{int f, t;cin >> n >> m;for(int i = 1; i <= m; ++i){cin >> f >> t;edge[f].push_back(t);edge[t].push_back(f);}for(int i = 1; i <= n; ++i) if(color[i] == 0){color[i] = 1;ct[1] = 1, ct[2] = 0;if(!dfs(i)){cout << "Impossible" << endl;return 0;}ans += min(ct[1], ct[2]);}cout << ans;return 0;
}
- 写法2:广搜二分染色
#include<bits/stdc++.h>
using namespace std;
#define N 10005
int n, m, color[N], ct[3], ans;//ct[1]、ct[2]颜色1的数量和颜色2的数量
vector<int> edge[N];
bool bfs(int sv)
{queue<int> que;que.push(sv);while(!que.empty()){int u = que.front();que.pop();for(int v : edge[u]){if(color[v] == 0){color[v] = 3-color[u];ct[color[v]]++;que.push(v); }else if(color[v] == color[u])return false;}}return true;
}
int main()
{int f, t;cin >> n >> m;for(int i = 1; i <= m; ++i){cin >> f >> t;edge[f].push_back(t);edge[t].push_back(f);}for(int i = 1; i <= n; ++i) if(color[i] == 0){color[i] = 1;ct[1] = 1, ct[2] = 0;if(!bfs(i)){cout << "Impossible" << endl;return 0;}ans += min(ct[1], ct[2]);}cout << ans;return 0;
}