Programmation de la semaine de réflexion 7 affectation B-Airport Express

Le titre

Aujourd'hui, il a ouvert une émission en direct du voyage sur la station B, enregistrant ses aventures avec le chat magique lors d'un voyage sur le chat. TT part de chez lui et se prépare à prendre le Cat Express jusqu'à l'aéroport Meow Star. La ligne chat chat express est divisée en ligne économique et ligne commerciale, leur vitesse et leur prix sont différents. Bien sûr, la ligne commerciale est plus chère que la ligne économique.TTT ne peut généralement prendre que la ligne économique, mais aujourd'hui le chat magique de TT a changé pour un billet de ligne commerciale et peut prendre une ligne commerciale. En supposant que le temps de transfert TT soit négligeable, veuillez aider TT à trouver l'itinéraire le plus rapide pour l'aéroport de Miaoxing, sinon vous manquerez l'avion!

Contribution

L'entrée contient plusieurs ensembles de données. La première ligne de chaque ensemble de données est de 3 entiers N, S et E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ 100), qui est le nombre total de stations, point de départ et point d'arrivée (c'est-à-dire la station où se trouve l'aéroport Meowing) ) Numéro.
La ligne suivante contient un entier M (1 ≤ M ≤ 1000), qui est le nombre de sections de la ligne économique.
Ensuite, il y a M lignes, chaque ligne de 3 entiers X, Y, Z (1 ≤ X, Y ≤ N, 1 ≤ Z ≤ 100), ce qui signifie que TT peut prendre la ligne économique vers et depuis la station X et la station Y, dont une façon Cela prend Z minutes.
Le nombre de segments de route dans la ligne suivante de la ligne commerciale est K (1 ≤ K ≤ 1000).
La ligne suivante K est une description du segment de ligne commerciale, le format est le même que la ligne économique.
Toutes les sections sont bidirectionnelles, mais il peut être nécessaire d'utiliser un billet commercial pour rejoindre l'aéroport. Assurez-vous que la solution optimale est unique.

Ouput

Pour chaque ensemble de données, sortez 3 lignes. La première ligne donne les stations (y compris le point de départ et le point d'arrivée) que TT traverse dans l'ordre d'accès, et la deuxième ligne est le numéro de station du transfert TT vers la ligne commerciale (si le ticket de ligne commerciale n'est pas utilisé, sortez "Ticket non utilisé" sans guillemets) ), La troisième ligne correspond au temps total passé par TT à l'aéroport de Meow Star.
Cette question n'ignore pas les espaces et les tabulations supplémentaires, et une nouvelle ligne est générée entre chaque ensemble de réponses.

Exemple d'entrée

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

Exemple de sortie

1 2 4
2
5

Des idées

Cette question donne le point de départ et le point d'arrivée, et la ligne commerciale peut être utilisée au plus une fois (de sorte que chaque ligne commerciale peut être énumérée). Énumérer chaque secteur d'activité (uvw), calculer le chemin le plus court du point de départ à u et le chemin le plus court de v au point d'arrivée plus le temps w passé par le secteur d'activité.
Utilisez dijkstra pour trouver le chemin le plus court d'une source unique sans bords négatifs.
ÀLe point de départ est le point sourceTrouvez la source unique la plus courte, obtenezdis1 []; PourLe point final est le point sourceTrouvez la source unique la plus courte, obtenezdis2 []. Énumérer les secteurs d'activité (u, v, w), prendremin {dis1 [u] + dis2 [v] + w, dis1 [v] + dis2 [u] + w}Pour obtenir l'itinéraire le plus court le long de la ligne commerciale. Comparez avec l'itinéraire le plus court qui ne prend pas la ligne commerciale et prenez le plus petit.

Dijkstra

Utilisé pour résoudre la figurePas de bord négatifDeSource unique la plus courteProblème.

Complexité O ((n + m) logn).

Processus de mise en œuvre:

  • Soit s le point source, dis [a] représente le chemin le plus court du point source s au point a, initialisedis [s] = 0 , dis [i] = inf, Wills rejoindre le tas minimum
  • Chaque fois que le haut x de la pile est pris de la pile, toutes les arêtes critiques (xyw) de x sont traversées,Comparez la taille de dis [y] et dis [x] + w. -Fonctionnement lent
  • Sidis [y]> dis [x] + w, La détente est réussie.Mettre à jour dis [y]La taille dey rejoindre le tas minimum
  • Continuez à effectuer les opérations ci-dessus jusqu'à ce que le segment minimal soit vide et que la matrice de disques résultante soit enregistrée comme la valeur de court-circuit la plus courte de la source unique.

Puisqu'il n'y a que des bords positifs dans le graphique, chaque point ne sera éjecté qu'une seule fois par le tas minimum, c'est-à-dire qu'une fois qu'un point est éjecté par le tas minimum, il ne sera plus relâché et la valeur de dis est le chemin le plus court.

Code

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
struct Edge{
    int to,w,next=-1;
}edge[2005];
const int inf=1e8;
int n,s,e,m,k,head[505],tot,dis1[505],dis2[505],path1[505],path2[505];
bool vis[505];
priority_queue<pair<int,int>> q;

void add(int x,int y,int w){
    edge[++tot].to=y;
    edge[tot].next=head[x];
    edge[tot].w=w;
    head[x]=tot;
}

void dijkstra(int s,int *dis,int *path){
    while(q.size())
        q.pop();
    memset(vis, false, sizeof(vis));
    path[s]=-1;dis[s]=0;
    q.push(make_pair(0, s));
    while(q.size()){
        int x=q.top().second;
        q.pop();
        if(vis[x])//访问过,取下一个点
            continue;
        vis[x]=true;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int y=edge[i].to,w=edge[i].w;
            if(dis[y]>dis[x]+w){
                dis[y]=dis[x]+w;
                q.push(make_pair(-dis[y], y));
                path[y]=x;
            }
        }
    }
}

int main() {
    bool firstInput=true;
    while(scanf("%d%d%d",&n,&s,&e)!=EOF){
        for(int i=1;i<=n;i++){
            dis1[i]=inf;
            dis2[i]=inf;
            path1[i]=-1;
            path2[i]=-1;
            head[i]=-1;
        }
        tot=0;
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x, y, z);
            add(y, x, z);
        }
        dijkstra(s, dis1, path1);
        dijkstra(e, dis2, path2);
        int u,v,ans=inf;
        scanf("%d",&k);
        for(int i=0;i<k;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(dis1[x]+dis2[y]+z<ans){
                u=x;v=y;
                ans=dis1[x]+dis2[y]+z;
            }
            if(dis1[y]+dis2[x]+z<ans){
                u=y;v=x;
                ans=dis1[y]+dis2[x]+z;
            }
        }
        if(firstInput)
            firstInput=false;
        else
            printf("\n");
        vector<int>vec;
        if(dis1[e]<ans){//不使用商业线
            for(int i=e;i!=s;i=path1[i])
                vec.push_back(i);
            vec.push_back(s);
            for(int i=(int)vec.size()-1;i>0;i--)
                printf("%d ",vec[i]);
            printf("%d\nTicket Not Used\n%d\n",vec[0],dis1[e]);
        }
        else{//使用商业线
            for(int i=u;i!=s;i=path1[i])
                vec.push_back(i);
            vec.push_back(s);
            for(int i=(int)vec.size()-1;i>=0;i--)
                printf("%d ",vec[i]);
            for(int i=v;i!=e;i=path2[i])
                printf("%d ",i);
            printf("%d\n",e);
            printf("%d\n%d\n",u,ans);
        }
    }
}

Résumé

Cette question a commencé avec memset (vis, false, sizeof (vis)) dans la fonction principale, et j'ai oublié de l'initialiser avant le deuxième dijkstra, wa pendant longtemps.
Lien de titre

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43805228/article/details/105410058
conseillé
Classement