牛客假日团队赛8

emmmmm<—在这里
A题 最小支配集

//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>
 
#define INF 0x3f3f3f3f
#define MAXN 10005
const int mod = 1e9 + 7;
 
using namespace std;
 
struct node {
    int to;
    int next;
}edge[MAXN<<1];
 
int from[MAXN];
bool vis[MAXN];
int parent[MAXN];
int newpos[MAXN];
int cnt_1;
int cnt_2;
int N;
 
void add(int x, int y) {
    edge[++cnt_1].next = from[x];
    edge[cnt_1].to = y;
    from[x] = cnt_1;
}
 
void dfs(int x) {
    vis[x] = true;
    newpos[cnt_2++] = x;
    for (int i = from[x]; i; i = edge[i].next) {
        int k = edge[i].to;
        if (!vis[k])
            parent[k] = x, vis[k] = true, dfs(k);
    }
}
 
int f1(void) {
    set<int> s1;
    memset(vis, 0, sizeof(vis));
    for (int i = cnt_2 - 1; i >= 0; i--) {
        int x = newpos[i];
        if (!vis[x]) {
            s1.insert(parent[x]);    //切记判重 
            vis[x] = true;
            vis[parent[x]] = true;
            vis[parent[parent[x]]] = true;
        }
    }
    return s1.size();
}
 
int main()
{
    //freopen("data.txt", "r", stdin);
 
    cin >> N;
 
    for (int i = 1; i < N; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
        add(b, a);
    }
 
    dfs(1);
 
    cout << f1() << endl;
 
     
 
    //freopen("CON", "r", stdin);
    //system("pause");
    return 0;
}

D题 不知道啥题

//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>

#define INF 0x3f3f3f3f
#define MAXN 100005		// 1e5
#define maxn 1005		// 1e3

const int mod = 1e9 + 7;

using namespace std;

struct node {
	long long a;
	long long b;
	int l;
	int r;
}edge[MAXN];

long long ans[MAXN];

int main()
{
	//freopen("data.txt", "r", stdin);

	int N;
	cin >> N;
	int k = 0;
	int minn = INF;
	
	for (int i = 1; i <= N; i++) {
		scanf("%lld%lld", &edge[i].a, &edge[i].b);
		if (minn > edge[i].b)
			minn = edge[i].b, k = i;
	}

	for (int i = 0; i <= N + 1; i++) {
		edge[i].l = i - 1;
		edge[i].r = i + 1;
	}

	edge[0].a = 1;
	edge[0].b = INF;
	edge[N + 1].a = 1;
	edge[N + 1].b = INF;

	int cnt = 1;
	long long sum = 0;
	int l, r;
	l = r = k;

	while (cnt <= N) {
		sum += edge[k].a;
		ans[k] = sum;

		l = edge[k].l;
		r = edge[k].r;
		sum += (min(edge[l].b, edge[r].b) - edge[k].b - 1)*edge[k].a;

		edge[r].l = l;
		edge[l].r = r;

		if (edge[l].b < edge[r].b) {
			edge[l].a += edge[k].a;
			k = l;
		}
		else {
			edge[r].a += edge[k].a;
			k = r;
		}

		while (1) {
			l = edge[k].l;
			r = edge[k].r;
			if (edge[k].b > edge[l].b)
				k = l;
			else if (edge[k].b > edge[r].b)
				k = r;
			else
				break;
		}
		cnt++;
	}

	for (int i = 1; i <= N; i++)
		printf("%lld\n", ans[i]);

	//freopen("CON", "r", stdin);
	//system("pause");
	return 0;
}

E题 还不会。。。

//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>
 
#define INF 0x3f3f3f3f
#define MAXN 1000005
#define maxn 1005
 
const int mod = 1e9 + 7;
 
using namespace std;
 
struct node {
    int a;
    int b;
    int c;
}edge[25005];
node a[25005];
 
int f[MAXN];
int N, K;
 
void init(void) {
    for (int i = 1; i <= N; i++)
        f[i] = i;
}
 
int find(int x) {
    if (x == f[x])
        return x;
    return f[x] = find(f[x]);
}
 
bool cmp(node x, node y) {
    return x.c > y.c;
}
 
bool f1(int tot) {
 
    init();
    for (int i = 1; i <= tot; i++)
        a[i] = edge[i];
 
    sort(a + 1, a + 1 + tot, cmp);
 
    for (int i = 1, j = 1; i <= tot; i = j) {
        j = i;
        int L, l;
        L = l = edge[i].a;
        int R, r;
        R = r = edge[i].b;
 
        while (a[++j].c == a[i].c && j < tot) {
            L = min(L, a[j].a), R = max(R, a[j].b);
            l = max(l, a[j].a), r = min(r, a[j].b);
        }
 
        if (l > r || l > find(r))
            return false;
 
        //染色
        while (L <= R) {
            if (find(R) == R)
                f[R--] = find(L - 1);  //特别注意一下 应该是find(L-1)
            else
                R = f[R];               //父节点
        }
 
    }
    return 1;
}
 
int main()
{
    //freopen("data.txt", "r", stdin);
 
    cin >> N >> K;
 
    for (int i = 1; i <= K; i++)
        scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].c);
 
    int l = 1, r = K;
    int ans = 0;
    while (l <= r) {
        int mid = l + r >> 1;
        if (f1(mid)) {
            l = mid + 1;
        }
        else {
            ans = mid;
            r = mid - 1;
        }
    }
 
    cout << ans << endl;
     
 
     
 
    //freopen("CON", "r", stdin);
    //system("pause");
    return 0;
}

F题 二分+最短路

//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>

#define INF 0x3f3f3f3f
#define MAXN 100005		// 1e5
#define maxn 1005		// 1e3

const int mod = 1e9 + 7;

using namespace std;

struct node {
	int to;
	int next;
	int cost;
}edge[MAXN];

int from[maxn];
int cnt_1;
int N, P, K;
int D[maxn];

void add(int x, int y, int t) {
	edge[++cnt_1].next = from[x];
	edge[cnt_1].to = y;
	edge[cnt_1].cost = t;
	from[x] = cnt_1;
}

bool f1(int mid) {
	priority_queue < pair<int, int >, vector < pair<int, int > >, greater<pair<int, int > > > q1;
	q1.push(make_pair(0, 1));
	memset(D, 0x3f, sizeof(D));
	D[1] = 0;
	while (!q1.empty()) {
		pair<int, int > P;
		P = q1.top();
		q1.pop();
		if (D[P.second] < P.first)
			continue;
		for (int i = from[P.second]; i; i = edge[i].next) {
			int dd;
			if (edge[i].cost >= mid)
				dd = D[P.second] + 1;
			else
				dd = D[P.second];
			if (D[edge[i].to] > dd)
				D[edge[i].to] = dd ,q1.push(make_pair(D[edge[i].to], edge[i].to));
		}
	}
	return D[N] <= K;
}

int main()
{
	//freopen("data.txt", "r", stdin);


	cin >> N >> P >> K;

	for (int i = 0; i < P; i++) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b, c);
		add(b, a, c);
	}
	int l = 0, r = 1000000 + 2;
	while (r >= l) {
		int mid = r + l >> 1;
		if (f1(mid))
			r = mid - 1;
		else
			l = mid + 1;
	}
	if (l > 1000000)
		cout << -1 << endl;
	else
		cout << l << endl;

	

	//freopen("CON", "r", stdin);
	//system("pause");
	return 0;
}

K题 最短路变形

//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>

#define INF 0x3f3f3f3f
#define MAXN 105
const int mod = 1e9 + 7;

using namespace std;

int mp[MAXN][MAXN];
int cnt[MAXN];
int N, M;

int main()
{
	//freopen("data.txt", "r", stdin);


	cin >> N >> M;
	memset(mp, 0x3f, sizeof(mp));

	for (int i = 0; i <= M; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		mp[b][a] = 1;
	}

	for (int i = 1; i <= N; i++)
		mp[i][i] = 0;

	for (int k = 1; k <= N; k++) {
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++)
				mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
		}
	}
	int anss = 0;
	for (int i = 1; i <= N; i++) {
		int temp = 1;
		for (int j = 1; j <= N; j++) {
			if (mp[i][j] == INF && mp[j][i] == INF) {
				temp = 0;
				break;
			}
		}
		if (temp)
			anss++;
	}
	

	cout << anss << endl;

	//freopen("CON", "r", stdin);
	//system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值