CF1240F Football

题目传送门

分析:
先转化一下模型,把队伍看作点,两个队伍比赛看作边,给边\(K\)染色,假设以点\(i\)为端点,颜色最大的值为\(mx_i\),最小为\(mn_i\)
我们需要找到染色方案使得对于每一个点\(i\)\(mx_i-mn_i\leq 2\)
不知道所有的比赛是否都可以举行,我们先尝试看看能不能每条边都染色
先思考\(K=2\)的情况吧,我们新建节点0,如果一个点度数为奇数,将这个点与0连边
接下来这个图的每个点度数都为偶数了
接下来在这个图上胡乱dfs,保证所有边只经过一次,把这些边按顺序加入队列
把这些边按加入顺序的奇偶性染色,再删去0和与0相连的边
可以保证每个点\(mx_i-mn_i\leq 1\)
非常巧妙的构造,可以联系一下欧拉回路证明其正确性
访问一个点再离开,入边和出边在队列里相邻,必定不同色,可以被抵消二保证\(mx_i-mn_i=0\)
删除0点后度数为奇数的点最多被删一条边,也能保证\(mx_i-mn_i=1\)
对于\(K>2\)的情况,我们先随机染色,然后找到某个不合法的点出现最多的颜色\(C_1\),和最少的颜色\(C_2\)
\(C_1,C_2\)\(K=2\)的方法染色,这样我们会让\(mx_i-mn_i\)不断缩小,最后求得答案
这样可以求得让每一条边都染色的合法方案,即每一场比赛都能举行
(不会证明QAQ,感性理解感觉很对2333)
最坏情况复杂度\(O(nm^2)\),由于随机跑不满,可以通过(
(可能是我的写太丑了常数巨大,随机种子多试了几次才过的

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define maxn 1105
#define MOD 1000000007

using namespace std;

inline int getint()
{
	int num=0,flag=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
	return num*flag;
}

int n,m,K;
struct node{
	int u,v,col;
}E[maxn];
int D[105][maxn],d[105];
int C1=1,C2=1;
vectorG[105],Id[105];
int vis[maxn],stk[maxn],tp;

inline bool check()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=K;j++)
		{
			if(D[i][j]>D[i][C1])C1=j;
			if(D[i][j]2)return 0;
	}
	return 1;
}

inline void dfs(int u)
{
	for(int i=0;i

你可能感兴趣的:(CF1240F Football)