Pagini recente » Cod sursa (job #2529662) | Cod sursa (job #2327457) | Cod sursa (job #180000) | Cod sursa (job #3243470) | Cod sursa (job #2766704)
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 50000 //cincizeci de mii
using namespace std;
ifstream fin ("distante.in");
ofstream fout ("distante.out");
int N, M, S;
int dimHeap;
int dist[NMAX + 1];
int distPres[NMAX + 1];
vector < pair<int, int> > G[NMAX + 1];
bool viz[NMAX + 1];
int pozHeap[NMAX + 1];
int origine[NMAX + 1];
int H[NMAX + 1];
int comparareHeap(int first, int second){
//-1 daca first < second
//0 egale
//1 daca first > second
if(dist[ H[first] ] < dist[ H[second] ]){
return -1;
}
else if(dist[ H[first] ] == dist[ H[second] ]){
return 0;
}
else {
return 1;
}
}
void swapHeap(int first, int second){ //pozitiile din heap trebuiesc primite aici!
swap(H[first], H[second]);
swap(pozHeap[ origine[first] ], pozHeap[ origine[second] ]);
swap(origine[first], origine[second]);
}
void sift(int poz){
//adica in jos
int son = 1;
while(son){
son = 0;
int left = poz * 2;
int right = poz * 2 + 1;
if(left <= dimHeap){
son = left;
}
if(right <= dimHeap && comparareHeap(right, left) < 0){ // right mai mic ca left
son = right;
}
if( son != 0 && comparareHeap(poz, son) == 1 ){ //poz > son
swapHeap(poz, son);
poz = son;
}
else {
son = 0;
}
}
}
void percolate(int poz){
//adica in sus
while(poz != 1 && comparareHeap(poz, poz / 2) < 0){ // poz mai mic ca poz / 2
swapHeap(poz, poz / 2);
poz = poz / 2;
}
}
void adaugareHeap(int node){
dimHeap++;
H[dimHeap] = node;
origine[dimHeap] = node;
pozHeap[node] = dimHeap;
percolate(dimHeap);
}
int areCopiiMaiMici(int poz){
int son = 0;
int left = poz * 2;
int right = poz * 2 + 1;
if(left <= dimHeap){
son = left;
}
if(right <= dimHeap && comparareHeap(right, left) < 0){ //right < left
son = right;
}
if(son == 0){
return 0;
}
else {
if(comparareHeap(son, poz) < 0){ //son < poz
return 1;
}
else {
return 0;
}
}
}
int areTataMaiMare(int poz){
if(poz == 1){
return 0;
}
//acum poz sigur nu e radacina
int father = poz / 2;
if( comparareHeap(poz, father) < 0 ){ //poz < father
return 1;
}
else {
return 0;
}
}
void stergereHeap(int node){
if(dimHeap == 1 || pozHeap[node] == dimHeap){
dimHeap--;
return;
}
//un heap cu minim doua elemente aici, unde pozHeap[node] != dimHeap
int poz = pozHeap[node];
//printf("Dau swap in heap la (%d, %d)\n", poz, dimHeap);
//printf("(%d, %d)\n", H[poz], H[dimHeap]);
swapHeap(poz, dimHeap);
//printf("(%d, %d)\n\n", H[poz], H[dimHeap]);
dimHeap--;
if( areCopiiMaiMici(poz) ){ //e prea sus atunci, il duc jos
//printf("Dau sift!\n");
sift(poz);
}
else if( areTataMaiMare(poz) ){ //e prea jos atunci, il duc sus
//printf("Dau percolate!\n");
percolate(poz);
}
}
void adaugareVeciniInHeap(int node){
for(int i = 0; i < G[node].size(); i++){
int vec = G[node][i].first;
int cost = G[node][i].second;
if(!viz[vec]){
viz[vec] = 1;
dist[vec] = dist[node] + cost;
adaugareHeap(vec);
}
}
}
void resetareMemorie(){
for(int i = 1; i <= N; i++){
viz[i] = 0;
dist[i] = 0;
}
dimHeap = 0;
for(int i = 1; i <= N; i++){
G[i].clear();
}
}
/*
void afisareHeap(){
for(int i = 1; i <= dimHeap; i++){
printf("H[ %d ] = %d\n", i, H[i]);
}
printf("\n\n");
}
*/
int BFS(int start){
viz[start] = 1;
dist[start] = 0;
adaugareHeap(start);
while( dimHeap != 0 ){
//iau varful, adica cel mai apropiat de sursa
int node = H[1];
//printf("Aleg %d\n", node);
if(dist[node] != distPres[node]){
return 0;
}
adaugareVeciniInHeap(node);
//afisareHeap();
stergereHeap(node);
//afisareHeap();
}
//printf("\n!!!\n");
return 1;
}
int main()
{
int nrTeste;
fin >> nrTeste;
for(int test = 1; test <= nrTeste; test++){
resetareMemorie();
fin >> N >> M >> S;
for(int i = 1; i <= N; i++){
fin >> distPres[i];
}
for(int i = 1; i <= M; i++){
int x, y, cost;
fin >> x >> y >> cost;
G[x].push_back( {y, cost} );
G[y].push_back( {x, cost} );
}
if( BFS(S) ){
fout << "DA\n";
}
else {
fout << "NU\n";
}
}
return 0;
}