2023 ICPC合肥

赛时4题和gxd两个人打的。
一人切了两题思路然后我写了三题。B题思路其实已经对了遗憾没有过
F签到,略

J:

首先把问题拆分为1-u的距离加上v-n的距离再加上u-v的距离就变成了一个可做题。
如果是我自己写的话可能会在bfs的时候用优先队列排序,但是队友想的是先排序然后从小到大连边加并查集。
一个的复杂度主要在于过程中排序,另一个就直接优化了一个log(如果我没算错的话),然后均摊了一个o(n)。还是很值得学习。
但是这是一个单源的问题,还是比较简单。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 1000,inf=1e9;
#define pipii pair<int,pair<int,int> >
#define mkp make_pair


int fa1[maxn],fan[maxn],dis1[maxn],disn[maxn];
vector<pipii> edg;
vector<int> E1[maxn],En[maxn];


int find1(int x){
    if(fa1[x]==x)
        return x;
    return fa1[x]=find1(fa1[x]);
}
int findn(int x){
    if(fan[x]==x)
        return x;
    return fan[x]=findn(fan[x]);
}


int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n;i++)
        fa1[i] = i, fan[i] = i,E1[i].push_back(i),En[i].push_back(i);
    dis1[1] = 0, disn[n] = 0;
    for (int i = 1; i <= m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        edg.push_back(mkp(w, mkp(u, v)));
    }
    sort(edg.begin(), edg.end());
    int ans = 2e9;
    for(auto i:edg){
        int w = i.first, u = i.second.first, v = i.second.second;
        int fu = find1(u), fv = find1(v);
        if(fu!=fv){
            if(fu<fv)
                swap(fu, fv), swap(u, v);
            if(fv==1){
                for(auto j:E1[fu])
                    dis1[j] = w;
                fa1[fu] = 1;
            }
            else{
                if(E1[fu].size()<E1[fv].size())
                    swap(fu, fv), swap(u, v);
                for(auto j:E1[fv]){
                    E1[fu].push_back(j);
                }
                fa1[fv] = fu;
                E1[fv].clear();
            }
        }
        fu = findn(fan[u]), fv = findn(fan[v]);
        if(fu!=fv){
            if(fu<fv)
                swap(fu, fv), swap(u, v);
            if(fu==n){
                for(auto j:En[fv])
                    disn[j] = w;
                fan[fv] = n;
            }
            else{
                if(En[fu].size()<En[fv].size())
                    swap(fu, fv), swap(u, v);
                for(auto j:En[fv]){
                    En[fu].push_back(j);
                }
                fan[fv] = fu;
                En[fv].clear();
            }
        }
        if( 1==find1(n) && 1==find1(u)){
            ans = min(ans, max(dis1[u],disn[v])+w);
            ans = min(ans, max(dis1[v],disn[u]) + w);
        }
    }
    cout << ans << endl;
}

E:

队友写的

G:

cf典题,一眼二分+DP,不会的人一定是没打cf吧,哈哈。

B:

dp题

C:

回文自动机板子,但是没人会字符串啊

posted @ 2024-10-04 18:36  lyrrr  阅读(18)  评论(0)    收藏  举报