cf Round 621 abcd

A Cow and Haybales standard input/output 2 s, 256 MB Submit Add to favourites x7258

  模拟即可,
B Cow and Friend standard input/output 2 s, 256 MB Submit Add to favourites x5283

   如果 ai == x 可以一步到, 否则输出 max(2, ceil(x/max_ai)), 不会证明 结论是猜的 
C Cow and Message standard input/output 2 s, 256 MB Submit Add to favourites x3759

  可以把出现次数最多的秘密串 只取 第一个 或 前两个字母, 出现次数不变 所以问题变成求 出现次数最多的 一个字母 或 两个字母组成的串, DP
D Cow and Fields standard input/output 2 s, 256 MB Submit Add to favourites x1636

  n 个点 m 条边的无向图, 其中有 k 个点属于特殊点 必须选两个点建一条边(边可已存在), 求建边以后 1 -> n 的最长的 最短路  可以理解为 先找 一条最短路

  然后 求建一条边以后最短路受影响最小的那条边,
    题解为找到一条最长的边  1 -> x -> y -> n, 然后可以把 1->x 设为 ax  n->x 设为 bx, bfs两次 分别从 顶点 1 和 n 求出每个点的ax 和 bx, 需要找最大的 ax + by

    所以可以将 ax+by <= ay+bx   ->   ax-bx <= ay-by   将每个特殊点的 ax-bx 存入数组, 排个序  遍历下 找出最大的 ax+by

    最后和 dist[1->n] 和 ax+by+1 取个min 即可, 代码如下

#include <bits/stdc++.h> //cf 621 div1+div2
using namespace std;
#define ll long long
#define _for(i,a,b) for(int i = (a); i < (b); i++) 
#define _rep(i,a,b) for(int i = (a); i <= (b); i++)
#define sz(z) (v).size()
void taskA(){
    int t; cin >> t;
    while(t--) {
        int n,d; cin >> n >> d;
        vector<int> a(n);
        _for(i,0,n) cin >> a[i];
        _for(i,1,n) {
            if(d <= 0) break;   
            if(a[i])  
                //{int x = min(a[i], d/i); a[0] += x, d -= x*i;}
                {int x = min(a[i]*i, d); a[0] += x/i; d -= x; }
            //cout << " i = " << i << " d = " << d << "\n";
        } cout << a[0] << "\n";
    }
    return;
}
void taskB(){
    int t; cin >> t;
    while(t--) {
        int n,x,ma = 0; cin >> n >> x;
        set<int> s;
        _for(i,0,n) {
            int k; cin >> k;
            ma = max(ma, k);
            s.insert(k);
        }
        if(s.count(x)) cout << "1\n";
        else cout << max(2, (x+ma-1)/ma) << "\n";
    }
    return;
}
void taskC(){
    // the secret message can be cut to one or two chars
    //that doesn't change the times
    string s; cin >> s;
    int n = s.size();
    ll ans = 0, arr1[26] = {}, arr2[26][26] = {};
    _for(i,0,n) {
        int k = s[i]-'a';
        _for(j,0,26) arr2[j][k] += arr1[j];
        // count(ab) = count(ab) + count(a)
        arr1[k]++;
    }
    _for(i,0,26) {
        ans = max(ans, arr1[i]);
        _for(j,0,26) ans = max(ans, arr2[i][j]);
    }
    cout << ans << "\n";
    return;
}
const int N = 2e5+10;
const int INF = 1e9+7;
int dist[2][N]; 
int n,m,k,q[N]; 
vector<int> g[N];
void bfs(int s, int* dis){
    fill(dis, dis+n+1, INF);// zz
    int t = 0, t1 = 0;
    dis[s] = 0;
    q[t++] = s;
    _for(i,0,t) {
        int u = q[i];
        for(auto it : g[u]) {
            if(dis[it] > dis[u]+1){
                dis[it] = dis[u]+1;
                q[t++] = it;
            }
        }
    }
    return;
}
void taskD(){
    cin >> n >> m >> k;
    vector<int> a(k); _for(i,0,k) cin >> a[i];
    sort(a.begin(), a.end());
    _for(i,0,m) {
        int x,y; cin >> x >> y;
        if(x > y) swap(x, y);
        g[x].push_back(y); g[y].push_back(x);
    }
    bfs(1, dist[0]);
    bfs(n, dist[1]);
    vector<pair<int, int> > mp;
    _for(i,0,k) 
     mp.emplace_back(dist[0][a[i]]-dist[1][a[i]], a[i]);
    sort(mp.begin(), mp.end());

    int be = 0, ma = 0;
    _for(i,0,k) {
        int x = mp[i].second;
        if(i) be = max(be, ma+dist[1][x]);
        ma = max(ma, dist[0][x]);
    }
    //cout << "be = " << be << " ma = " << ma << "\n";
    cout << min(dist[0][n], be+1);
    return;
}
int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    //taskA();
    //taskB();
    //taskC();
    taskD();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/163467wyj/p/12343971.html
今日推荐