蓝桥杯 - 卡勒沃夫之弱水路三千(提高型)

简介: 蓝桥杯 - 卡勒沃夫之弱水路三千(提高型)

题目链接:点击打开链接


题目大意:略。


解题思路:字符串数组绑定下标 + 拓扑排序(邻接表)。


AC 代码

1.#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
vector<string> vec; // 存储字符串,为了匹配对应的位置
map<string,int> mp; // 记录是否访问过
const int MAXV=1000;
// mk:匹配字符串的位置
// inrr:存取入度
// rcd:记录最终结果
int mk[200][10],inrr[MAXV],rcd[MAXV];
// n:组数
// len:实际结点个数
int n,len;
struct ENode
{
    int adjvex;
    int weight;
    ENode *next;
};
typedef struct VNode
{
    int in;
    int data;
    ENode *firstE;
}AdjList[MAXV];
typedef struct gAList
{
    AdjList adjList;
    int numV,numE;
}*GAList;
void init()
{
    len=0;
    mp.clear();
    vec.clear();
    vec.push_back("#"); // 为了从 1 开始,因为 mp 第二参数 int 默认为 0
    mem(mk,0);
    mem(inrr,0);
    mem(rcd,0);
}
// 拓扑排序
int TopoSort(GAList GAL)
{
    ENode *e;
    int top=0;
    int cnt=0;
    int *sk;
    sk=(int *)malloc((GAL->numV)*sizeof(int)); // 存入度为 0 的结点
    for(int i=1;i<=GAL->numV;i++) // 因为从 1 开始,这里也得从 1 开始
        if(GAL->adjList[i].in==0)
            sk[++top]=i; // ++top 从1开始,为下文 while(top!=0) 做准备
    while(top!=0)
    {
        int gettop=sk[top--]; // 取出入度为 0 的结点
//        printf("%d -> ",GAL->adjList[gettop].data);
        rcd[cnt++]=GAL->adjList[gettop].data; // 记录结果
        for(e=GAL->adjList[gettop].firstE; e; e=e->next)
        {
            int k=e->adjvex;
            if(!(--GAL->adjList[k].in))
                sk[++top]=k;
        }
    }
    if(cnt<GAL->numV)
        return 0;
    else
        return 1;
}
// 调试(可忽略)
void showVec()
{
    for(int i=1;i<=vec.size()-1;i++)
    {
        printf("%s ",vec[i].c_str());
    }
    puts("");
}
// 调试(可忽略)
void showMP()
{
    for(int i=1;i<=vec.size()-1;i++)
    {
        printf("mp[ %s ] == %d\n",vec[i].c_str(),mp[vec[i].c_str()]);
    }
    puts("");
}
// 调试(可忽略)
void showMK()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=2;j++)
        {
            printf("%d ",mk[i][j]);
        }
        puts("");
    }
}
int main()
{
    int T; scanf("%d",&T);
    while(T-- && ~scanf("%d",&n))
    {
        init();
        int cnt=1,first=1;
        for(int i=1;i<=n;i++)
        {
            int j=1;
            string a,b;
            int x,y;
            cin>>a>>b;
            if(first)
            {
                first=0;
                vec.push_back(a);
                mp[a]=cnt; x=cnt++;
                vec.push_back(b);
                mp[b]=cnt; y=cnt++;
            }
            if(mp[a]==0)
            {
                vec.push_back(a);
                mp[a]=cnt; x=cnt++;
            }
            else
                x=mp[a];
            if(mp[b]==0)
            {
                vec.push_back(b);
                mp[b]=cnt; y=cnt++;
            }
            else
                y=mp[b];
            mk[i][j++]=x; // 1,1 开始
            mk[i][j++]=y;
            inrr[y]++;
//            showVec();
//            showMP();
        }
        len=cnt-1; // 结点个数
//        showMK();
        // 创建 GAL
        GAList GAL=new gAList;
        GAL->numV=len;
        for(int i=1;i<=len;i++)
        {
            VNode &curV=GAL->adjList[i];
            curV.data=i;
            curV.in=inrr[i];
            curV.firstE=NULL;
        }
        for(int i=1;i<=n;i++)
        {
            VNode &curV=GAL->adjList[mk[i][1]];
            ENode *e=new ENode;
            e->adjvex=mk[i][2];
            e->next=curV.firstE;
            curV.firstE=e;
        }
        // 调试(可忽略)
//        for(int i=1;i<=len;i++)
//        {
//            VNode &curV=GAL->adjList[i];
//            printf("adjList[%d]:\n",i);
//            printf("in == %d\n",curV.in);
//            printf("data == %d\n",curV.data);
//            printf("firstE == %d\n",curV.firstE);
//            puts("");
//        }
        TopoSort(GAL);
        for(int i=0;i<len;i++)
        {
            if(i==0)
                printf("%s",vec[rcd[i]].c_str());
            else
                printf(" %s",vec[rcd[i]].c_str());
        }
        puts("");
    }
    return 0;
}
目录
相关文章
|
4月前
|
搜索推荐
蓝桥杯-基础练习 数列排序
蓝桥杯-基础练习 数列排序
55 0
|
3月前
|
存储 索引
6/1 第十五届蓝桥杯国赛pb组 真题本人答案 仅供参考
6/1 第十五届蓝桥杯国赛pb组 真题本人答案 仅供参考
50 4
|
4月前
|
C语言
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
|
4月前
|
测试技术
蓝桥杯(基础题)
蓝桥杯(基础题)
33 1
|
4月前
|
存储 Java API
第十三届蓝桥杯B组Java(试题A:星期计算)
第十三届蓝桥杯B组Java(试题A:星期计算)
57 0
|
存储 Java
湖南大学Java编程题3. 计算int型二进制1的个数
湖南大学Java编程题3. 计算int型二进制1的个数
蓝桥杯-经典枚举案例
必须要一个数组来存放0-9每个卡片的余额,每个数组下标对应各自卡片【下标为0代表卡片0的数量】
|
算法 搜索推荐 小程序
2021年度Leetcode算法类型高频题总结&(附答案解析)
昨晚逛了逛GitHub,无意中看到一位P8大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到。
127 0
2021年度Leetcode算法类型高频题总结&(附答案解析)