文件构建

题目理解

对一定数量的文件排序,其中文件存在依赖关系,即在处理A文件时必须已经处理好B文件,需要安排处理文件的顺序。
输入:文件数量 文件依赖关系
依赖关系1
依赖关系2
...

思路

用图:有向的图
解不是唯一的。但最后需要给出一个线性的排列。
拓扑:把一个有向图转换成一个线性的排列。
实现方法:
1.找到入度为0的点,加入结果集;
2.删除该节点及该节点的连接关系;

代码实现

#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>

using namespace std;
int main(){
    int m,n,s,t;
    cin>>m>>n;
    vector<int> inDegree(m,0);
    unordered_map<int,vector<int>> umap;
    vector<int> result;
    while(n--){
        cin>>s>>t;
        inDegree[t]++;
        umap[s].push_back(t);
    }
    queue<int> que;
    for(int i=0;i<m;i++){
        if(inDegree[i]==0)
        {
            que.push(i);
        }
    }
    while(que.size()){
        int cur=que.front();
         que.pop();
         result.push_back(cur);
         vector<int> files=umap[cur];
         if(files.size()){
            for(int i=0;i<files.size();i++){
                inDegree[files[i]]--;
                if(inDegree[files[i]]==0){
                    que.push(files[i]);
                }
            }
         }
    }
    if(result.size()==m){
        for(int i=0;i<m-1;i++){
            cout<<result[i]<<" ";
            
        }
        cout<<result[m-1];
    }
    else cout<<-1<<endl;
    return 0;
}

问题:
alt text
在测试数据中发生了问题:输入的节点大于等于输入的节点个数会报数组越界,原因是在inDegree[]中,使用数组的索引,所以输入的节点是从0开始,并且连续。

小结

1.形成图:数据结构上,主要是采用umap对节点的关系进行组织。创建一个有m个存储空间,每一格节点映射到与其相连的下一个节点,以此形成图的结构。
2.输出图:使用队列实现广度搜索。

最短路径

题目理解

有N个节点,节点之间的连接有不同的时间权重,求从起点到终点的最小时间。
输入:N M
S1 E1 V1
S2 E2 V2
...

原始思路

1.求出起点到终点的所有路径并计算时间;
2.找出路径中时间花费最少的那一条。
如何找到起点到终点的路径?
起点是否可以到达终点?

确实和prim算法很相似,prim解决的是寻宝问题,每个节点都必须去到,本题则可以不经过某些节点,只要把起点和终点以最段路径相连即可。

djistra算法

1.维护未访问节点到远点的最小距离;
2.将该最小距离的节点标记为访问;
3.更新未访问节点到源点的最小距离。

代码实现

#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main(){
    int n,m,p1,p2,val;
    cin>>n>>m;
    //输入数据的存储
    vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));
    for(int i=0;i<m;i++){
        cin>>p1>>p2>>val;
        grid[p1][p2]=val;
    }
    //维护未访问节点到源点的最小距离
    int start=1;
    int end=n;
    vector<int> minDi(n+1,INT_MAX);
    vector<bool> visited(n+1,false);
    minDi[start]=0;
    for(int i=0;i<=n;i++){
        int minVal=INT_MAX;
        int cur=1;
        for(int j=1;j<=n;j++){
            if(!visited[j]&&minDi[j]<minVal){
                minVal=minDi[j];
                cur=j;
            }
        }
        //将之标记为已访问
        visited[cur]=true;
        //更新未访问节点到源点的最小距离
        for(int j=1;j<=n;j++){
            if(!visited[j]&&grid[cur][j]!=INT_MAX&&minDi[cur]+grid[cur][j]<minDi[j]){
                minDi[j]=minDi[cur]+grid[cur][j];
            }
        }
    }
    if(minDi[end]==INT_MAX) cout<<-1<<endl;
    else cout<<minDi[end]<<endl;
}

小结

计算了每一个节点距离源点的最小距离,类似于DP的思想,后一部分依赖于前一步的完成,后一步建立在前一步最佳之上。

posted on 2026-01-10 18:42  FAfa_C++  阅读(2)  评论(0)    收藏  举报