题解 签到题

传送门

结论:度数是 \(c\) 的倍数的点的贡献为 0,其余的点的贡献为 1
貌似猜结论比证明更好做

  • 关于图的染色:这里
    放个链接跑路吧:这里这里
    证明过程大意(好像)是先将每个点都尽量拆成度数为 \(c\) 的点
    由Vizing定理知这些度数为 \(c\) 的点一定能完成染色
    然后那些差一点不到 \(c\) 的就产生1的贡献
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#define ll long long
#define fir first
#define sec second
#define make make_pair
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (f=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, k, c;

namespace task1{
	int sta1[N], top1, sta2[N], top2, ans=INF;
	int cnta[N], cntb[N];
	int acol1[N], acol0[N], bcol1[N], bcol0[N];
	pair<int, int> e[N];
	void solve() {
		for (int i=1,a,b; i<=k; ++i) {
			a=read(); b=read();
			e[i]=make(a, b);
			++cnta[a]; ++cntb[b];
		}
		for (int i=1; i<=n; ++i) if (cnta[i]) sta1[++top1]=i;
		for (int i=1; i<=m; ++i) if (cntb[i]) sta2[++top2]=i;
		int lim=1<<k;
		for (int s=0; s<lim; ++s) {
			int sum=0;
			for (int i=1; i<=top1; ++i) acol1[sta1[i]]=acol0[sta1[i]]=0;
			for (int i=1; i<=top2; ++i) bcol1[sta2[i]]=bcol0[sta2[i]]=0;
			for (int i=0; i<k; ++i) {
				if (s&(1<<i)) {
					++acol1[e[i+1].fir]; ++bcol1[e[i+1].sec];
				}
				else {
					++acol0[e[i+1].fir]; ++bcol0[e[i+1].sec];
				}
			}
			for (int i=1; i<=top1; ++i) sum+=max(acol1[sta1[i]], acol0[sta1[i]])-min(acol1[sta1[i]], acol0[sta1[i]]);
			for (int i=1; i<=top2; ++i) sum+=max(bcol1[sta2[i]], bcol0[sta2[i]])-min(bcol1[sta2[i]], bcol0[sta2[i]]);
			ans=min(ans, sum);
		}
		printf("%d\n", ans);
		exit(0);
	}
}

namespace task{
	int cnta[N], cntb[N], ans;
	void solve() {
		for (int i=1,a,b; i<=k; ++i) {
			a=read(); b=read();
			++cnta[a]; ++cntb[b];
		}
		for (int i=1; i<=n; ++i) ans+=(cnta[i]%c!=0);
		for (int i=1; i<=m; ++i) ans+=(cntb[i]%c!=0);
		printf("%d\n", ans);
		exit(0);
	}
}

signed main()
{
	freopen("qiandao.in", "r", stdin);
	freopen("qiandao.out", "w", stdout);

	n=read(); m=read(); k=read(); c=read();
	// if (c==1) {puts("0"); return 0;}
	// else if (c==2) task1::solve();
	task::solve();

	return 0;
}
posted @ 2021-10-07 20:37  Administrator-09  阅读(8)  评论(0编辑  收藏  举报