题意:有两组士兵,分别为a和b,一对一互相攻打,每个士兵的生命值等于对方的攻击值减掉自己的生命值,问能否在a组士兵全部存活的情况下,b组全部阵亡
思路:比赛时没做出来,后来听到队长说是简单的二分图,就补了这方面的知识,对于a每一个士兵,在b中找到所有他能杀死别人且自己不死的士兵,这两者建一条从a->b的边,
就是求最大匹配数目是否达到n,如果达到,输出Yes,否则输出No, solve里的代码可以当做求最大匹配数的dfs模板
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2232
#include <cstdio>
#include <cstring>
#include <algorithm>
#pragma warning (disable: 4996)
using namespace std;
const int maxn = 1005;
const int maxm = 10005;
struct edge
{
int u, v, next;
}e[maxm];
int head[maxn];
bool vis[maxn];
int n, cnt;
int a[maxn], b[maxn], c[maxn], d[maxn];
int from[maxn];
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
memset(from, -1, sizeof(from));
memset(vis, false, sizeof(vis));
}
void addedge(int u, int v)
{
e[cnt].u = u, e[cnt].v = v, e[cnt].next = head[u], head[u] = cnt++;
}
bool dfs(int u)
{
int v;
for (int i = head[u]; i !=- 1; i = e[i].next)
{
v = e[i].v;
if (!vis[v])
{
vis[v] = true;
if (from[v] == -1 || dfs(from[v]))
{
from[v] = u;
return true;
}
}
}
return false;
}
void solve()
{
bool flag = true;
for (int i = 1; i <= n; i++)
{
memset(vis, false, sizeof(vis));
if (!dfs(i))
{
flag = false;
puts("No");
break;
}
}
if (flag)
puts("Yes");
}
void build()
{
for (int i = 1; i <= n ; i++)
{
for (int j = 1; j <= n; j++)
{
if (b[i] >= c[j] && a[i] > d[j])
addedge(i, j + n);
}
}
}
void read()
{
int ret1 = 1, ret2 = 1;
scanf("%d", &n);//注意下输入
for (int i = 1; i <= n * 2; i++)
{
if (i & 1)
scanf("%d", &a[ret1++]);
else
scanf("%d", &b[ret2++]);
}
ret1 = ret2 = 1;
for (int i = 1; i <= n * 2; i++)
{
if (i & 1)
scanf("%d", &c[ret1++]);
else
scanf("%d", &d[ret2++]);
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
init();
read();//读入数据
build();//建边
solve();//求最大匹配
}
return 0;
}