D Alex and Julian
题意:已知集合B,可以把|i-j|属于B的点连一条线构成图。问从B中最少删多少点能使图为二分图。
无向图G为二分图的充分必要条件是:G至少有两个顶点,并且其所有回路的长度均为偶数。
将造成回路长度为奇数的点删去;
如果选中了数a,那么…,a/4,a/2,2a,4a,…都是不能选的;
即如果能够共存,它们的2的幂次数应该是一样的;
所以其实这是个数论题?
就只是用了二分图的性质
不好想啊
我是想不出来的
…
#pragma warning(disable:4996)
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<map>
#include<cmath>
#include<set>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
ll b[maxn];
set<ll> sett[105];
int main()
{
freopen("in.txt", "r", stdin);
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &b[i]);
ll temp = b[i];
int cnt = 0;
while (!(temp & 1)) {
cnt++;
temp >>= 1;
}
sett[cnt].insert(b[i]);
}
int maxindex = 0;
int maxx = sett[0].size();
for (int i = 1; i <= 64; i++) {
if (maxx < sett[i].size()) {
maxx = sett[i].size();
maxindex = i;
}
}
printf("%d\n", n-maxx);
for (int i = 0; i <= 64; i++) {
if (i == maxindex)continue;
else {
for (auto it : sett[i]) {
printf("%lld ", it);
}
}
}
}
E Tourism
题意:已知一个无向图。无自环、保证联通。每个点有一个权值。Alex可从sta点开始,使走过的点的权值和最大(每个点只能加一次),并且不可以连续通过一条边两次。
思路:可以想一想要连续通过一条边两次的情况:该边是个桥,并且点v不在环内。
所以可以用tarjan先缩个点,得到一个无环图,就是个树。要是该点是通过缩点所得那就可以重复走它连着的边,不是通过缩点所得那走过去后就不能回走了。
但是这样是错的=-=太繁琐了,codeforces的题怎么能这么麻烦的写呢?
所以正解其实是…
void dfs(int x,int fa) {
vis[x]=1;
for(auto v:e[x]) {
if(v==fa) continue;
if(vis[v]) t[x]=1;
else dfs(v,x),t[x]|=t[v];
}
if(!t[x]) {
for(auto v:e[x]) if(v!=fa) s[x]=max(s[x],s[v]);
s[x]+=w[x];
}
}