SDUT 2022 Winter Individual Contest - C(AC)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDUT 2022 Winter Individual Contest - C(AC)相关的知识,希望对你有一定的参考价值。

链接: link.

C - Crowd Control

题意:

给定 n n n个点 m m m条边的无向图,每条边都有一个容量,从起点 0 0 0到终点 n − 1 n-1 n1的容量,取决于路径上的最小容量,为了使从起点到终点容量最大化,需要删除一些边,以便于从 0 0 0走到 n − 1 n-1 n1的最小容量是最大的,并把删除的边的编号由小到大输出

思路:

先套 s p f a spfa spfa最大化最小边,并记录下路径,把从 0 0 0 n − 1 n-1 n1的路径存下来后,再通过两重循环,或者 d f s dfs dfs把不是对应路径上的边,都记下来,然后排序去重输出即可,由于是链式前向星存的是无向边,找答案就按有一条边来算就行,所以就是 i + = 2 i+=2 i+=2,边的编号就是链式前向星中的编号 / 2 /2 /2
也可以通过二分 + B F S +BFS +BFS来实现最大化最小边,然后再找到路径,再删除非路径的边,或者最大生成树
链接: link.

#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 10;
const int inf = 0x7fffffff;
int ue[N], h[N], e[N], ne[N], w[N], idx;
int dis[N], vis[N], pre[N];
int n, m;
int st, ed;
vector<int> path;
vector<int> res;
void add_edge(int a, int b, int c) 
    ue[idx] = a;
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;


void spfa() 
    memset(dis, 0, sizeof(dis));
    queue<int> q;
    q.push(st);
    dis[st] = inf;
    vis[st] = 1;
    while (!q.empty()) 
        int t = q.front();
        q.pop();
        vis[t] = 0;
        for (int i = h[t]; ~i; i = ne[i]) 
            int j = e[i];
            if (dis[j] < min(dis[t], w[i])) 
                dis[j] = min(dis[t], w[i]);
                pre[j] = t;
                if (!vis[j]) 
                    vis[j] = 1;
                    q.push(j);
                
            
        
    

void dfs1(int u) 
    path.push_back(u);
    vis[u] = 1;
    if (u == 0) return;
    dfs1(pre[u]);


void dfs2(int n) 
    int now = path[n];
    if (n == 0) 
        for (int i = 0; i < idx; i += 2) 
            if (ue[i] == now && e[i] != path[n + 1] ||
                e[i] == now && ue[i] != path[n + 1]) 
                res.push_back(i / 2);
            
        
        return;
     else 
        for (int i = 0; i < idx; i += 2) 
            if (ue[i] == now && e[i] != path[n + 1] && e[i] != path[n - 1] ||
                e[i] == now && ue[i] != path[n + 1] && ue[i] != path[n - 1]) 
                res.push_back(i / 2);
            
        
        dfs2(n - 1);
    

int main() 
    memset(h, -1, sizeof(h));
    scanf("%d%d", &n, &m);
    for (int i = 0, a, b, c; i < m; i++) 
        scanf("%d%d%d", &a, &b, &c);
        add_edge(a, b, c);
        add_edge(b, a, c);
    
    st = 0, ed = n - 1;
    spfa();
    memset(vis, 0, sizeof(vis));
    dfs1(ed);
    dfs2(path.size() - 1);

    sort(res.begin(), res.end());
    res.erase(unique(res.begin(), res.end()), res.end());

    if (res.size() == 0) 
        puts("none");
     else 
        for (int i = 0; i < res.size(); i++) 
            printf("%d ", res[i]);
        
    

A - Abandoned Animal

题意:

给定 n n n个超市的位置编号,和他们所卖的商品,现在给定一份 m m m行的购买商品的清单,问按照清单列举的顺序买东西,所走的路径是唯一的,不确定的,还是不存在的

思路:

开二维 v e c t o r vector vector,来存超市与商品的关系,然后先按照在清单顺序的情况下,多个商店符合条件的话,优先去位置最近的商店,再按照在清单顺序的情况下,多个商品符合条件,游仙区位置最远的商店,然后看两种遍历方法的路径是否一样,如果无法遍历成功,就是不存在,如果路径相同就是唯一,不相同就是不确定

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int> shop[N];
map<string, int> mp;
int a[N];
char s[20];
int n, k, m;
int id;
int idx = 1;
vector<int> pre;
vector<int> suf;
int main() 
    cin >> n >> k;

    for (int i = 0; i < k; i++) 
        scanf("%d%s", &id, s);
        if (mp[s]) 
            shop[id].push_back(mp[s]);
         else 
            mp[s] = idx;
            shop[id].push_back(idx++);
        
    
    cin >> m;
    for (int i = 0; i < m; i++) 
        scanf("%s", s);
        a[i] = mp[s];
    

    int cur = 0;
    int flag = 0;

    for (int i = 0; i < n && cur < m; i++) 
        int len = shop[i].size();

        for (int j = 0; j < len; j++) 
            if (shop[i][j] == a[cur]) 
                pre.push_back(i);
                cur++;
                i--;
                break;
            
        
    

    if (pre.size() == m) 
        flag++;
    

    cur = m - 1;

    for (int i = n - 1; i >= 0 && cur >= 0; i--) 
        int len = shop[i].size();
        for (int j = len - 1; j >= 0; j--) 
            if (shop[i][j] == a[cur]) 
                suf.push_back(i);
                cur--;
                i++;
                break;
            
        
    

    if (suf.size() == m) 
        flag++;
    

    if (flag == 0) 
        puts("impossible");
     else if (flag == 1) 
        puts("unique");
     else 
        bool f = 0;
        reverse(suf.begin(), suf.end());
        for (int i = 0; i < m; i++) 
            if (pre[i] != suf[i]) 
                f = 1;
                break;
            
        
        if (f)
            puts("ambiguous");
        else
            puts("unique");
    

    return 0;

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于SDUT 2022 Winter Individual Contest - C(AC)的主要内容,如果未能解决你的问题,请参考以下文章

SDUT 2022 Winter Team Contest - 1

SDUT 2022 Winter Individual Contest - A(D)

SDUT 2022 Winter Individual Contest - D(K)

SDUT 2022 Winter Individual Contest - D(K)

SDUT 2022 Winter Individual Contest - D(K)

SDUT 2022 Winter Individual Contest - A(D)