-
Notifications
You must be signed in to change notification settings - Fork 1
/
1931.cpp
130 lines (122 loc) · 2.75 KB
/
1931.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <bits/stdc++.h>
using namespace std;
typedef struct vertice{
int val, peso;
struct vertice *prox;
}Vertice;
typedef struct grafo
{
int v,e;
vertice *adj;
}Grafo;
Grafo* criaGrafo(int v)
{
Grafo *g = (Grafo*) malloc(sizeof(Grafo));
if (g!=NULL)
{
g->v = v;
g->e = 0;
g->adj = (vertice*)calloc(v,sizeof(vertice));
//todas as adjacencias estarao vazias neste momento
for (int i = 0; i <v; ++i)
{
g->adj[i].prox = NULL;
}
}
return g;
}
vertice* novoVertice(int v, int peso)
{
vertice *novo = (vertice*)malloc(sizeof(vertice));
novo -> val = v;
novo -> peso = peso;
novo -> prox = NULL;
return novo;
}
void insereAresta(Grafo *g, int v1, int v2,int peso)
{
if(v1!=v2)//se nao for laco
{
vertice *p = g->adj[v1].prox;
while(p!=NULL)
{
if(p->val == v2) break; //verifica se o vertice ja esta ligado
p = p->prox;
}
/*se terminou de percorrer lista e não achou ocorrencia
do novo vertice, insere o vertice na lista
so verifica uma vez pois se trata de grafo simples
*/
if(p==NULL)
{
//insere novo vertice na adj de v1
vertice *novo = novoVertice(v2,peso);
novo->prox = g -> adj[v1].prox;
g->adj[v1].prox = novo;
//repete para v2
novo = novoVertice(v1,peso);
novo->prox = g->adj[v2].prox;
g->adj[v2].prox = novo;
g->e++;
}
}
}
int main(){
int cities,estrada,c1,c2,peso, i;
cin >> cities >> estrada;
Vertice *v;
//essa bagulheira aqui é pra deixar prioridade minima
priority_queue<pair<int, int>, vector<pair<int, int> >,greater<pair<int, int> > > Abertos; // dist[],city
Grafo *g = criaGrafo(cities);
//pi : predecessores, dist: distancia de v0, verificado: vertice ja foi verificado
int *pi, *dist,*numPedagios;
pi = (int*)calloc(cities,sizeof(int));
dist = (int*)malloc(cities* sizeof(int));
numPedagios = (int*)calloc(cities, sizeof(int));
//gera grafo com as arestas de entrada
for (i = 0; i < estrada;i++)
{
if(i < cities)
{
dist[i] = INT_MAX;
// numPedagios[i] = -1;
}
cin >> c1 >>c2 >>peso;
insereAresta(g, c1-1, c2-1,peso);
cin.clear();
}
//prepara origem
pi[0]--;
dist[0] = 0;
Abertos.push(make_pair(dist[0],0) );
int u,distU;
//dijkstra
while(Abertos.size()>0)
{
u = Abertos.top().second;
distU = Abertos.top().first;
Abertos.pop();
v = g->adj[u].prox;
while(v!= NULL)
{
if(distU + v->peso < dist[v->val])
{
Abertos.push(make_pair(dist[v->val],v->val));
dist[v->val] = distU + v->peso;
numPedagios[v->val]++;
if(v->val != cities-1)
{
pi[v->val] = u;
//insere os adjascentes a U na lista de prioridade minima
}
}
v = v->prox;
}
}
for (int i = 0; i < cities; ++i)
{
cout<<dist[i]<<"\t";
}cout<<"\n";
//se conseguiu chegar ao fim com numero par de pedagios há um caminho minimo para la
return 0;
}