20211123 HDU exercise shortest path and minimum spanning tree

Some template titles are dijkstra and prim

I'm sorry to copy and paste the experiment report the first time I write a blog. I'll do it well next time. ()

In the future, I will also write some questions.   Welcome to play with me~

HDU Today

Time Limit : 15000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)

Total Submission(s) : 40   Accepted Submission(s) : 2

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

With the help of Jin Nang, Haidong Group has finally passed the crisis. Since then, the development of HDU has been smooth. By 2050, the group has been quite large, and is said to have entered the top 500 of Qianjiang Meat Silk Economic Development Zone. At this time, the XHD couples also retired from the second line and bought a house in Taoyao village, Lipu town, Zhuji, which is a beautiful place to spend their old age.
After living in this way for a while, Xu always didn't know much about the local traffic. Sometimes very depressed, want to go to a place and don't know what bus to take, where to change, where to get off (in fact, Xu always has his own car, but must be happy with the people, which is Xu's general character).
Xu always asks the way in bad English: "Can you help me?". Looking at his confused and helpless eyes, can you help him warmly?
Help him to get to his destination in the shortest possible time (assuming that each bus stops only at the starting and ending points and always leaves).

Input

The input data has multiple groups, the first row of each group is the total number of buses N (0<=N<=10000);
The second line has Xu's general location, start, and his destination, end.
Then there are n rows, each with a station name s, a station name e, and a time integer t (0 < T < 100) from s to e (each place name is a string not longer than 30).
note: No more than 150 place names in a set of data.
If N==-1, the input ends.

Output

If Xu can always reach the destination, the output time is the shortest. Otherwise, output'-1'.

Sample Input

6

xiasha westlake

xiasha station 60

xiasha ShoppingCenterofHangZhou 30

station westlake 20

ShoppingCenterofHangZhou supermarket 10

xiasha supermarket 50

supermarket westlake 10

-1

Sample Output

Analysis of Topics

For the shortest path problem, the difficult point is not to enter a number but a place name as a string at each node.

And no sample output

Solution: Use a map <string, int> to number by place name and key value. STL really works!

dijkstra with priority queue optimization

Code

#include<bits/stdc++.h>

using namespace std;



#define INF 0x3f3f3f3f



int n;

int graph[155][155];

string start,endd;

int dis[105];

bool vis[105];



int main(){

    int t,cnt,i;

    string s,e;

    map<string,int> mapp;

    while(1){

        cin >> n;

        if(n==-1)   break;

        cin >> start >> endd;

        mapp.clear();

        memset(graph,INF,sizeof(graph));

        cnt=1;

        mapp[start]=1;

        if(!mapp[endd])    mapp[endd]=++cnt;

        while(n--){

            cin >> s >> e >> t;

            if(!mapp[s])    mapp[s]=++cnt;

            if(!mapp[e])    mapp[e]=++cnt;

            //cout << s << " " << mapp[s] << endl;

            //cout << e << " " << mapp[e] << endl;

            graph[mapp[s]][mapp[e]]=graph[mapp[e]][mapp[s]]=t;

        }

        memset(vis,false,sizeof(vis));

        memset(dis,INF,sizeof(dis));

        vis[0]=true;

        dis[1]=0;

        priority_queue<pair<int,int>> q;    //(-length, node number)

        for(i=2;i<=n;i++){

            dis[i]=graph[1][i];

            if(dis[i]!=INF){

                q.push(make_pair(-dis[i],i));

            }

        }

        q.push(make_pair(-0,1));

        while(!vis[mapp[endd]]){

            i=0;

            while(vis[i]){

                i=q.top().second;

                q.pop();                

            }

            vis[i]=true;

            for(int j=1;j<=cnt;j++){

                if(!vis[j] && dis[j]>dis[i]+graph[i][j]){

                    dis[j]=dis[i]+graph[i][j];

                    q.push(make_pair(-dis[j],j));

                }

            }

        }

        if(dis[mapp[endd]]!=INF) cout << dis[mapp[endd]];

        else    cout << "-1";

        cout << endl;

    }

    return 0;

}

Code Running

Beautiful

What's your feeling?

When working with shortest path/minimum spanning tree problems, you need some habits:

  1. Is there a double edge?
  2. Are there negative edges/circles? (Select a different algorithm)
  3. Do you need to output a path or just calculate the path length?
  4. According to the graph, the selection algorithm is sparse or dense (we haven't encountered very strict problems yet)
  5. It's always right to optimize. It's always right to use scanf more than cin

Unblocked project

Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)

Total Submission(s) : 90   Accepted Submission(s) : 20

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

The goal of the provincial government's "unblocked project" is to enable highway traffic between any two villages in the province (but not necessarily directly connected by highways, as long as indirectly accessible by highways). After investigation and assessment, the resulting statistical table lists the cost of several roads that might be built. Now please write a program to calculate the lowest cost for unimpeded access in the whole province.

Input

The test input contains several test cases. Line 1 of each test case gives the number of roads and villages evaluated N (< 100); Subsequent N
Rows correspond to the cost of roads between villages, and each row gives a pair of positive integers, the number of two villages, and the cost of roads between the two villages (also a positive integer). For simplicity, the villages are numbered from 1 to M. When N is 0, all inputs end and the corresponding results are not output.

Output

For each test case, output the lowest cost for provincial unimpedence in one line. If statistics are insufficient to ensure unimpeded, output'?'.

Sample Input

3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100

Sample Output

3
?

Source

Computer Postgraduate Re-examination Entrance Examination of Zhejiang University-2007

Analysis of Topics

Minimum spanning tree problem. Use the prim algorithm, because you are not sure about the size of the N, or risk not using kruskal (in fact, the dijkstra was written in the previous topic)

Code

#include<bits/stdc++.h>

using namespace std;



#define INF 0x3f3f3f3f



int main(){

    int n,m,i,j,k,visted,ans;

    int w[105][105];

    int dis[105];

    bool vis[105];

    while(1){

        cin >> n >> m;

        if(n==0)    break;

        memset(w,INF,sizeof(w));

        while(n--){

            cin >> i >> j >> k;

            if(w[j][i]>k)   w[i][j]=w[j][i]=k;

        }

        ans=visted=0;

        memset(dis,INF,sizeof(dis));

        memset(vis,false,sizeof(vis));

        priority_queue<pair<int,int>> q;

        dis[1]=0;   vis[0]=true;

        for(i=2;i<=m;i++){

            dis[i]=w[1][i];

            if(dis[i]!=INF){

                q.push(make_pair(-dis[i],i));

            }

        }

        q.push(make_pair(0,1));

        while(!q.empty()){

            i=0;

            while(vis[i] && (!q.empty())){

                i=q.top().second;

                q.pop();

            }

            if(i==0)    break;

            vis[i]=true;

            visted++;

            ans+=dis[i];

            for(j=2;j<=m;j++){

                if((!vis[j]) && dis[j]>w[i][j]){

                    dis[j]=w[i][j];

                    q.push(make_pair(-dis[j],j));

                }

            }

        }

        if(visted==m)   cout << ans << endl;

        else cout << "?" << endl;



    }

    return 0;

}

Code Running

Beautiful

What's your feeling?

Skeptical of Kruskal's scenario, I decided to find something to do.

Or smooth engineering

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)

Total Submission(s) : 40   Accepted Submission(s) : 15

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

A province surveys rural traffic conditions and the resulting statistical tables list the distances between any two villages. The goal of the provincial government's "unblocked project" is to enable highway traffic between any two villages in the province (but not necessarily direct highway connection, as long as it can be reached indirectly) and to require the total length of the roads to be paved to a minimum. Please calculate the minimum total road length.

Input

The test input contains several test cases. Line 1 of each test case gives the number of villages N (< 100); The subsequent N(N-1)/2 rows correspond to the distance between the villages, and each row gives a pair of positive integers, the number of the two villages and the distance between the two villages. For simplicity, villages are numbered from 1 to N.
When N is 0, the input ends and the use case is not processed.

Output

For each test case, output the minimum total road length in one line.

Sample Input

3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0

Sample Output

3
5

Hint

Hint
Huge input, scanf is recommended.

Source

Computer Postgraduate Re-examination Entrance Examination of Zhejiang University-2006

Analysis of Topics

Or minimum spanning tree problem. This time it's a dense map. Maybe it means that kruskal is going to be written in 1002.      TT.

Change it with the previous code, but today's topic has no negative edges.

Notice the exit condition of the loop and exit when all vertices have been visited (visted==m).

Code

#include<bits/stdc++.h>

using namespace std;



#define INF 0x3f3f3f3f



int main(){

    int n,m,i,j,k,visted,ans;

    int w[105][105];

    int dis[105];

    bool vis[105];

    while(1){

        cin >> m;

        n=m*(m-1)/2;

        if(m==0)    break;

        memset(w,INF,sizeof(w));

        while(n--){

            //cin >> i >> j >> k;

            scanf("%d%d%d",&i,&j,&k);

            if(w[j][i]>k)   w[i][j]=w[j][i]=k;

        }

        ans=visted=0;

        memset(dis,INF,sizeof(dis));

        memset(vis,false,sizeof(vis));

        priority_queue<pair<int,int>> q;

        dis[1]=0;   vis[0]=true;

        for(i=2;i<=m;i++){

            dis[i]=w[1][i];

            if(dis[i]!=INF){

                q.push(make_pair(-dis[i],i));

            }

        }

        q.push(make_pair(0,1));

        while(!q.empty()){

            i=0;

            while(vis[i] && (!q.empty())){

                i=q.top().second;

                q.pop();

            }

            if(i==0 || visted==m)   break;

            vis[i]=true;

            visted++;

            ans+=dis[i];

            for(j=2;j<=m;j++){

                if((!vis[j]) && dis[j]>w[i][j]){

                    dis[j]=w[i][j];

                    q.push(make_pair(-dis[j],j));

                }

            }

        }

        /*

        cout << visted << endl;

        if(visted==m)   cout << ans << endl;

        else cout << "?" << endl;

        */

        cout << ans << endl;

    }

    return 0;

}

Code Running

Beautiful

What's your feeling?

Blank here

shortest path

Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)

Total Submission(s) : 114   Accepted Submission(s) : 30

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

Every year in the school competition, all the finalists get a beautiful t-shirt. But every time our staff brought hundreds of clothes back from the store, they were very tired! So now they want to find the shortest route from the store to the race field, can you help them?

Input

The input includes multiple sets of data. The first row of each set of data is two integers N and M (N<=100, M<=10000). N indicates that there are several intersections on the streets of Chengdu. The Street labeled 1 is the location of stores, the intersection labeled N is the location of race sites, and M indicates that there are several roads in Chengdu. N=M=0 means the end of input. The next M lines, which consist of three integers A, B, C (1<=A, B<=N, 1<=C<=1000), indicate that there is a road between intersection A and intersection B, and our staff need C minutes to walk this road.
Enter a route that guarantees at least one store to the venue.

Output

For each set of inputs, output a line indicating the shortest time a worker can walk from the store to the race field

Sample Input

2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0

Sample Output

3
2
 
 

Source

UESTC 6th Programming Contest Online

Analysis of Topics

Shortest path, dijkstra.

Code

#include<bits/stdc++.h>

using namespace std;



#define INF 0x3f3f3f3f



int main(){

    int n,m,i,j,k,visted;

    int w[105][105];

    int dis[105];

    bool vis[105];

    while(1){

        //cin >> n >> m;

        cin >> m >> n;

        if(n==0 && m==0)    break;

        memset(w,INF,sizeof(w));

        while(n--){

            cin >> i >> j >> k;

            if(w[j][i]>k)   w[i][j]=w[j][i]=k;

        }

        visted=0;

        memset(dis,INF,sizeof(dis));

        memset(vis,false,sizeof(vis));

        vis[1]=true;

        dis[1]=0;

        for(i=2;i<=m;i++){

            dis[i]=w[1][i];

        }

        for(i=2;i<=m;i++){

            int min,pos;

            min=INF;

            for(j=2;j<=m;j++){

                if((!vis[j]) && dis[j]<min){

                    min=dis[j];

                    pos=j;

                }

            }

            if(min==INF)    break;

            vis[pos]=true;

            if(vis[m])  break;

            for(j=2;j<=m;j++){

                if((!vis[j]) && dis[j]>dis[pos]+w[pos][j]){

                    dis[j]=dis[pos]+w[pos][j];

                }

            }            

        }

        cout << dis[m] << endl;

    }

    return 0;

}

Code Running

Beautiful

What's your feeling?

Blank here

Shortest path problem

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)

Total Submission(s) : 25   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

Give you n points, m undirected edges, each edge has length d and cost p, give you start point s end point t, ask for the shortest distance from start point to end point and its cost, if the shortest distance has more than one route, the output will cost the least.

Input

Enter n,m, the number of the point is 1~n, followed by M lines, four numbers a,b,d,p per line, to indicate that there is a n edge between a a n d b, a n d its length is d, which costs p. The last line is two numbers s,t; Start s, end. The input ends when n and m are 0.
(1<n<=1000, 0<m<100000, s != t)

Output

The output line has two numbers, the shortest distance and its cost.

Sample Input

3 2
1 2 5 6
2 3 4 5
1 3
0 0

Sample Output

9 11

Source

Computer Postgraduate Re-examination Entrance Examination of Zhejiang University-2010

Analysis of Topics

Shortest path, dijkstra! It looks like some of your classmates wrote floyd, which is bound to time out.

Length d and cost p are actually primary and secondary keywords. Just be aware of the update criteria when updating dis[] and finding the next vertex to visit.

Then start and end points do not default to 1 and n, be careful when copying and pasting

Code

#include<bits/stdc++.h>

using namespace std;



#define INF 0x3f3f3f3f



int n,m,i,j,d,p,visted,s,t;

int w[1005][1005];

int mm[1005][1005];

int dis[1005],cost[1005];

bool vis[1005];



int main(){

    while(1){

        //cin >> n >> m;

        cin >> m >> n;

        if(n==0 && m==0)    break;

        memset(w,INF,sizeof(w));

        memset(mm,INF,sizeof(m));

        while(n--){

            //cin >> i >> j >> d >> p;

            scanf("%d%d%d%d",&i,&j,&d,&p);

            if((w[j][i]>d) || (w[j][i]==d && mm[j][i]>p)){

                w[i][j]=w[j][i]=d;

                mm[i][j]=mm[j][i]=p;

            }

        }

        scanf("%d%d",&s,&t);

        visted=0;

        memset(dis,INF,sizeof(dis));

        memset(vis,false,sizeof(vis));

        memset(cost,INF,sizeof(cost));

        for(i=1;i<=m;i++){

            dis[i]=w[s][i];

            cost[i]=mm[s][i];

        }

        vis[s]=true;

        dis[s]=0;

        cost[s]=0;

        for(i=1;i<=m;i++){

            int min,pos,mincost;

            mincost=min=INF;

            for(j=1;j<=m;j++){

                if((!vis[j]) && (dis[j]<min || (dis[j]==min && cost[j]<mincost))){

                    min=dis[j];

                    mincost=cost[j];

                    pos=j;

                }

            }

            if(min==INF)    break;

            vis[pos]=true;

            if(vis[t])  break;

            for(j=1;j<=m;j++){

                if((!vis[j]) && (dis[j]>dis[pos]+w[pos][j] || (dis[j]==dis[pos]+w[pos][j] && cost[j]>cost[pos]+mm[pos][j]))){

                    dis[j]=dis[pos]+w[pos][j];

                    cost[j]=cost[pos]+mm[pos][j];

                }

            }            

        }

        cout << dis[t] << " " << cost[t] << endl;

    }

    return 0;

}

Code Running

Beautiful

What's your feeling?

Care and care.

It's better to write a function for dijkstra and a function for conditional judgment. You can see it all together this time. The next time the title is more complex, it's not necessarily.

Tags: Graph Theory dijkstra Prim

Posted on Mon, 22 Nov 2021 19:35:33 -0500 by slamMan