11/17-提高组笔记

~ 2024-11-17 11:50:37

团伙

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<sstream>
#include<set>
#include<time.h>
#include<stdlib.h>
#include<unordered_map>
#define ll long long
#define ull unsigned long long
#define eps 1e-10
#define INF 1e9
#define delta 0.996
#define T 3000
#define pi acos(-1.0)
#define ld long double
using namespace std;
const ll mod1=1e9+7;
const ll mod2=998244353;
const int maxn = 2e5 + 10;
const int maxm = 2e5 + 10;
const ll inf=1e18L;
typedef pair<int,int>Pii;
typedef pair<int,ll>Pil;
using namespace std;
int father[5010], n, m, di[5010], ans;
int find(int x)
{
    if(father[x] == x) return x;
    else return father[x] = find(father[x]);
}
void unite(int x, int y)
{
    x = find(x);
    y = find(y);
    if(x == y) return;
    father[x] = y;
}
int same(int x, int y)
{
    if(find(x) == find(y)) return 1;
    else return 0;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        father[i] = i;
    }
    while(m--)
    {
        char c;
        int x, y;
        cin >> c >> x >> y;
        if(c == 'F') unite(x, y);
        else
        {
            // x之前还有别的敌人 di[x]
            // di[x]  和 y 是不是就有共同的敌人 x
            // 所以 di[x] 和 y 是好朋友,要合并
            if(di[x] == 0) di[x] = find(y); //没敌人
            else unite(di[x], y); //有敌人
            if(di[y] == 0) di[y] = find(x);
            else unite(di[y], x);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        if(find(i) == i) ans++;
    }
    cout << ans << '\n';
    return 0;
}

买礼物

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<sstream>
#include<set>
#include<time.h>
#include<stdlib.h>
#include<unordered_map>
#define ll long long
#define ull unsigned long long
#define eps 1e-10
#define INF 1e9
#define delta 0.996
#define T 3000
#define pi acos(-1.0)
#define ld long double
using namespace std;
const ll mod1=1e9+7;
const ll mod2=998244353;
const int maxn = 2e5 + 10;
const int maxm = 2e5 + 10;
const ll inf=1e18L;
typedef pair<int,int>Pii;
typedef pair<int,ll>Pil;
using namespace std;
int father[100010], A, B, n, cnt, cnt2;
int find(int x)
{
    if(father[x] == x) return x;
    else return father[x] = find(father[x]);
}
void unite(int x, int y)
{
    x = find(x);
    y = find(y);
    if(x == y) return;
    father[x] = y;
}
int same(int x, int y)
{
    if(find(x) == find(y)) return 1;
    else return 0;
}
struct edge
{
    int u, v, cost;
}e[200010];
int cmp(edge e1, edge e2)
{
    return e1.cost < e2.cost;
}
int kruskal()
{
    sort(e + 1, e + 1 + n, cmp);
    int res = 0;
    for(int i = 1; i <= n - cnt2; i++)
    {
        if(same(e[i].u, e[i].v) == 0)
        {
            res += e[i].cost;
            cnt++;
            unite(e[i].u, e[i].v);
        }
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> A >> B;
    for(int i = 1; i <= B; i++)
    {
        father[i] = i;
    }
    for(int i = 1; i <= B; i++)
    {
        for(int j = 1; j <= B; j++)
        {
            int x;
            cin >> x;
            if(i < j && x != 0)
            {
                n++;
                e[n] = {i, j, x};
                if(e[n].cost > A) cnt2++;
            }
        }
    }
    int ans = kruskal();
    if(cnt == B + 1) cout << ans + A << '\n';
    else cout << ans + A + (B - cnt - 1) * A << '\n';
    return 0;
}

prim 算法

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<sstream>
#include<set>
#include<time.h>
#include<stdlib.h>
#include<unordered_map>
#define ll long long
#define ull unsigned long long
#define eps 1e-10
#define INF 1e9
#define delta 0.996
#define T 3000
#define pi acos(-1.0)
#define ld long double
using namespace std;
const ll mod1=1e9+7;
const ll mod2=998244353;
const int maxn = 2e5 + 10;
const int maxm = 2e5 + 10;
const ll inf=1e18L;
typedef pair<int,int>Pii;
typedef pair<int,ll>Pil;
using namespace std;
//pair类型的优先队列默认用 .first 排序
//要把长度存在first位置,点存second
priority_queue<Pii, vector<Pii>, greater<Pii> >q;
struct edge
{
    int v, cost;
};
vector<edge>G[5010];
// vis 记录一个点是否已经选过
// dist 记录选入这个点的最小代价
int n, m, vis[5010], dist[5010], ans, cnt;
void prim()
{
    for(int i = 0; i <= n; i++) dist[i] = 1e9;
    dist[1] = 0;
    q.push({0, 1});
    while(q.empty() == 0)
    {
        Pii now = q.top(); q.pop();
        if(vis[now.second] == 1) continue;
        ans += now.first;
        cnt++;
        vis[now.second] = 1;
        if(cnt == n) break;
        // 松弛
        // 看一下 now.second 能连接着哪些点 : vector 遍历
        // G[1] = {2, 3, 4, 5};
        // G[1][0] = 2;
        // G[1][1] = 3;
        int siz = (int)G[now.second].size();
        for(int i = 0; i < siz; i++)//必须从0开始
        {
            edge e = G[now.second][i];
            // edge 结构体中有 e.v 表示点的编号 e.cost 表示边长
            // 如果 当前的 e.cost 小于 之前的代价
            // 说明当前的代价更好,我们就要更新,并把新的代价加入优先队列
            // eg:假设当前加入 2 号点的代价为 5
            // 即 e.cost = 5
            // 而 之前 2 号点可以被一号点加入,代价为 10
            // 即 dist[2] = 10;
            // 所以此时需要判断 e.cost < dist[2]  (5 < 10)
            // dist[2] 由 10 换成 5
            // 并把新的代价加入优先队列
            // e.cost 就是使得 e.v 选入的代价
            if(e.cost < dist[e.v])
            {
                dist[e.v] = e.cost;
                q.push({e.cost, e.v});
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        G[a].push_back({b, c});
        G[b].push_back({a, c});
    }
    prim();
    if(cnt == n) cout << ans << '\n';
    else cout << "orz\n";
    return 0;
}


我们会审查剪贴板内容,并对发布不合适内容的同学进行相应的处理