[[problem:AVOID]]
문제에서 코딩 실수가 있는 것 같은데, 찾지 못하겠어서 질문드립니다.
플로이드 알고리즘으로 D[i][j][k]에 각 최단 경로를 구했고,
이후 시작노드부터 최단경로로 소트하여 확률을 채워나갑니다.
E 클래스는 간선을 의미하고, F 클래스는 분수의 표현을 의미합니다.
저지에 제출하여 분모가 0이 아니라고 assert하는 부분에서 assertion failure가 나타납니다.
제가 만들어본 예제들에서는 나타나지 않는 문제인데, 어떻게 해결하면 좋을까요?
아래는 코드입니다.
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
using namespace std;
//class representing fractional numbers
class F
{
public:
int numer;
int denom;
F(int a, int b)
{
numer = a;
denom = b;
yakbun();
}
static F myAdd(F A, F B)
{
return F(A.numer * B.denom + A.denom * B.numer, A.denom * B.denom);
}
void myAdd(F A)
{
/*
numer = numer * A.denom + denom * A.numer;
denom *= A.denom;
yakbun();
*/
*this = F::myAdd(A, *this);
}
void yakbun()
{
int i = 2;
while(i*i <= numer && i*i <= denom)
{
while(numer %i == 0 && denom %i == 0)
{
numer /= i;
denom /= i;
}
i++;
}
}
F myDiv(int a)
{
return F(numer, denom * a);
//return F(this->numer, this->denom * a);
}
};
//class representing edge
class E
{
public:
int from, to, val;
E(int a, int b, int c)
{
from = a;
to = b;
val = c;
}
bool friend operator < (E A, E B)
{
return A.val < B.val;
}
};
void solve();
int main()
{
int T;
cin >> T;
while(T--)
solve();
}
void solve()
{
int N, M, targetSize;
vector <int> target;
vector <vector <E> > A;
vector <vector <int> > B;
cin >> N >> M >> targetSize;
A.resize(N);
B.resize(N);
for(int i=0; i<M; i++)
{
int temp1, temp2, temp3;
cin >> temp1 >> temp2 >> temp3;
A[temp1-1].push_back(E(temp1-1, temp2-1, temp3));
A[temp2-1].push_back(E(temp2-1, temp1-1, temp3));
}
for(int i=0; i<targetSize; i++)
{
int temp;
cin >> temp;
target.push_back(temp-1);
}
//floyd algorithm
int D[N][N][N+1];
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
for(int k=0; k<=N; k++)
D[i][j][k] = -1;
for(int i=0; i<N; i++)
for(int j=0; j<A[i].size(); j++)
D[A[i][j].from][A[i][j].to][0] = A[i][j].val;
for(int k=1; k<=N; k++)
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
if(D[i][k-1][k-1] != -1 && D[k-1][j][k-1] != -1)
D[i][j][k] = D[i][k-1][k-1] + D[k-1][j][k-1];
if(D[i][j][k-1] != -1 && D[i][j][k] != -1)
D[i][j][k] = min(D[i][j][k], D[i][j][k-1]);
else if(D[i][j][k-1] != -1)
D[i][j][k] = D[i][j][k-1];
}
for(int i=0; i<N; i++)
D[i][i][N] = 0;
//sort by distance from the starting vertex, and calculate probabillity in each vertex
vector <E> G;
for(int i=0; i<N; i++)
G.push_back(E(i,i,D[0][i][N]));
sort(G.begin(), G.end());
vector <F> FR;
FR.push_back(F(1,1));
for(int i=1; i<N; i++)
FR.push_back(F(0,1));
for(int i=0; i<N; i++)
{
int current = G[i].from;
//cout << i << "th time, spreading the node " << current << endl;
if(D[0][current][N] + D[current][N-1][N] != D[0][N-1][N])
continue;
vector <int> spread;
spread.clear();
for(int j=0; j<A[current].size(); j++)
if(D[current][A[current][j].to][N] + D[A[current][j].to][N-1][N] == D[current][N-1][N])
spread.push_back(A[current][j].to);
//cout << "it has value " << FR[current].numer << "/" << FR[current].denom << " and gonna divide it into " << spread.size() << " pieces" << endl;
for(int j=0; j<spread.size(); j++)
// cout << "spreading to the node : " << spread[j] << endl;
FR[spread[j]].myAdd(FR[current].myDiv((int)spread.size()));
}
for(int i=0; i<targetSize; i++)
cout << FR[target[i]].numer << "/" << FR[target[i]].denom << endl;
}
sven
[[problem:AVOID]]
문제에서 코딩 실수가 있는 것 같은데, 찾지 못하겠어서 질문드립니다.
플로이드 알고리즘으로 D[i][j][k]에 각 최단 경로를 구했고,
이후 시작노드부터 최단경로로 소트하여 확률을 채워나갑니다.
E 클래스는 간선을 의미하고, F 클래스는 분수의 표현을 의미합니다.
저지에 제출하여 분모가 0이 아니라고 assert하는 부분에서 assertion failure가 나타납니다.
제가 만들어본 예제들에서는 나타나지 않는 문제인데, 어떻게 해결하면 좋을까요?
아래는 코드입니다.
13년 전