POJ #2492 : A Bug's Life
传送门:http://poj.org/problem?id=2492
题意:二分图染色。
思路:利用bfs或者dfs遍历即可,没染色的进行染色,染过的判断两点颜色是否一样。
(PE的每个case要空一行)
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e18 + 10;
const double _e = 10e-6;
const int maxn = 2010;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int t, n, m;
vector<int> G[maxn];
int used[maxn];
bool bfs()
{
queue<int> que;
for (int i = 1; i <= n; i++) {
if (used[i] == -1) {
que.push(i); used[i] = 0;
while (!que.empty()) {
int u = que.front(); que.pop();
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (used[v] == -1) {
used[v] = (used[u] + 1) % 2;
que.push(v);
}
else if (used[v] == used[u])
return false;
}
}
}
}
return true;
}
int main()
{
scanf("%d", &t);
for (int _ = 1; _ <= t; _++) {
scanf("%d%d", &n, &m);
for (int i = 0; i <= 2000; i++)
G[i].clear();
cl1(used);
while (m--) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
printf("Scenario #%d:\n", _);
if (bfs())
puts("No suspicious bugs found!");
else
puts("Suspicious bugs found!");
printf("\n");
}
return 0;
}
POJ #2631 : Roads in the North
传送门:http://poj.org/problem?id=2631
题意:树上最远距离。
思路:先任取一点,求出到这点距离最远的点a,再求出点a到其他点的最远距离就是答案。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const int N = 410;
const double _e = 10e-6;
const int maxn = 10010;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, c;
int ans, ansid;
bool used[maxn];
struct node
{
int id;
int cost;
};
vector<node> G[maxn];
struct cmp
{
bool operator()(node a, node b)
{
return a.cost > b.cost;
}
};
void bfs(int u)
{
used[u] = true;
priority_queue<node, vector<node>, cmp> que;
que.push(node{ u,0 });
while (!que.empty()) {
int u = que.top().id, d = que.top().cost; que.pop();
ansid = u; ans = d;
for (int i = 0; i < G[u].size(); i++) {
node v = G[u][i];
if (!used[v.id]) {
used[v.id] = true;
que.push(node{ v.id,d + v.cost });
}
}
}
}
int main()
{
while (~scanf("%d%d%d", &x, &y, &c)) {
//if (x == 0)break;
G[x].push_back(node{ y,c });
G[y].push_back(node{ x,c });
}
cl0(used);
bfs(1);
cl0(used);
bfs(ansid);
printf("%d\n", ans);
return 0;
}
UVA #11080 : Place the Guards
传送门:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2021
题意:有n个路口,m条路,国王准备在某些路口安排一些人来把守。在一个路口把守的人能够把守与他所在的路口相连的所有路。问每条路都有且仅有一人把守,最少需要多少人。若无法满足则输出-1。
思路:将路口分为有人把守(路口0)的和没人把守的(路口1)。
对于所有路口来说,路口0必定与路口1相邻(不然就会有多人把守一条路或者压根没人把守某条路了)。
因此转化为二分图染色问题了。对于每块连通图都进行二分染色,然后取需要染色次数少的那种颜色,相加即为答案。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e18 + 10;
const double _e = 10e-6;
const int maxn = 210;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int t, n, m;
vector<int> G[maxn];
int used[maxn];
int bfs()
{
queue<int> que; int ans = 0;
for (int i = 0; i < n; i++) {
if (used[i] == -1) {
int ans0 = 0, ans1 = 0;
que.push(i); used[i] = 0; ans0++;
while (!que.empty()) {
int u = que.front(); que.pop();
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (used[v] == -1) {
used[v] = (used[u] + 1) % 2;
if (used[v] == 0)ans0++;
else ans1++;
que.push(v);
}
else if (used[v] == used[u])
return -1;
}
}
if (ans0 == 0 || ans1 == 0)
ans += max(ans0, ans1);
else
ans += min(ans0, ans1);
}
}
return ans;
}
int main()
{
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i <= 200; i++)
G[i].clear();
cl1(used);
while (m--) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
int ans = bfs();
printf("%d\n", ans);
}
return 0;
}
HDU #1372 : Knight Moves
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1372
题意:8*8的棋盘上,走马步从一个点到另一点的最短距离。
思路:利用bfs预处理所有点间的最短距离即可。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const int N = 410;
const double _e = 10e-6;
const int maxn = 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int xx[8] = { -2,-2,-1,1,1,-1,2,2 };
int yy[8] = { -1,1,2,2,-2,-2,1,-1 };
bool used[maxn][maxn];
int dis[maxn][maxn][maxn][maxn];
struct node
{
int x, y;
int d;
};
vector<node> G[maxn];
struct cmp
{
bool operator()(node a, node b)
{
return a.d > b.d;
}
};
void bfs(int ux, int uy)
{
used[ux][uy] = true; dis[ux][uy][ux][uy] = 0;
priority_queue<node, vector<node>, cmp> que;
que.push(node{ ux,uy,0 });
while (!que.empty()) {
node u = que.top(); que.pop();
for (int i = 0; i < 8; i++) {
int vx = u.x + xx[i], vy = u.y + yy[i];
if (vx <= 0 || vx > 8 || vy <= 0 || vy > 8)continue;
if (!used[vx][vy]) {
used[vx][vy] = true;
dis[ux][uy][vx][vy] = u.d + 1;
que.push(node{ vx,vy,u.d + 1 });
}
}
}
}
int main()
{
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
cl0(used);
bfs(i, j);
}
}
int x, y;
char x1, y1;
while (~scanf("%c%d %c%d", &x1, &x, &y1, &y)) {
getchar();
printf("To get from %c%d to %c%d takes %d knight moves.\n", x1, x, y1, y, dis[x1 - 'a' + 1][x][y1 - 'a' + 1][y]);
}
return 0;
}