思路很简单的一道题,吐了,写了半天,bug百出,写代码1小时,调试4小时。还得练,码力太弱。
#include <stdio.h>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxv = 1005;
const int INF = 100000000;
struct Node{
int v; //结点编号
int s; //边权(距离)
Node(int _v, int _s) : v(_v), s(_s) {}
};
vector<Node> G[maxv];
int weight[maxv][maxv];//第二判定;即代金券价值
int d[maxv],in[maxv] = {0};
bool vis[maxv] = {false};
int n, m, st, ed; //起点st是虚拟源点
bool topo()
{
int num = 0;
queue<int> q;
for(int i=0; i<n; i++){
if(in[i]==0){
q.push(i);
}
}
while(!q.empty()){
int front = q.front();
q.pop();
for(int i=0; i<G[front].size(); i++){
int v = G[front][i].v;
in[v]--;
if(in[v]==0){
q.push(v);
}
}
num++;
}
if(num==n) return true;
else return false;
}
vector<int> pre[maxv];
void Dijkstra(int s)
{
fill(d, d+maxv, INF);
d[s] = 0;
for(int i=0; i<=n; i++){
int u = -1, MIN = INF;
for(int j=0; j<=n; j++){
if(vis[j]==false && d[j]<MIN){
u = j;
MIN = d[j];
}
}
vis[u] = true;
for(int j=0; j<G[u].size(); j++){
int v = G[u][j].v; //第一处bug,G[u][j]误写成G[u][v],邻接矩阵写上头了。
if(vis[v]==false){
if(d[u]+G[u][j].s<d[v]){
d[v] = d[u]+G[u][j].s;
pre[v].clear();
pre[v].push_back(u);
}else if(d[u]+G[u][j].s==d[v]){
pre[v].push_back(u);
}
}
}
}
}
vector<int> path, tmpPath;
int maxValue;
void DFS(int v)
{
if(v==st){
tmpPath.push_back(v);
int value = 0;
for(int i=tmpPath.size()-1; i>0; i--){
int id1 = tmpPath[i], id2 = tmpPath[i-1];
value += weight[id1][id2];
}
if(value > maxValue){
maxValue = value;
path = tmpPath;
}
tmpPath.pop_back();
return;
}
tmpPath.push_back(v);
for(int i=0; i<pre[v].size(); i++){
DFS(pre[v][i]);
}
tmpPath.pop_back();
}
int main()
{
int t1, t2, s, dd, query;
scanf("%d%d", &n, &m);
st = n;
for(int i=0; i<m; i++){
scanf("%d%d%d%d", &t1, &t2, &s, &dd);
G[t1].push_back(Node(t2, s));
weight[t1][t2] = dd;
in[t2]++;
}
for(int i=0; i<n; i++){
if(in[i] == 0){
G[n].push_back(Node(i, 0));
weight[n][i] = 0;
}
}
Dijkstra(st);
scanf("%d", &query);
if(topo()){
printf("Okay.\n");
for(int i=0; i<query; i++){
scanf("%d", &ed);
maxValue = 0; //第二处bug,忘记擦屁股,每次要给maxValue重新赋值
DFS(ed);
if(d[ed]==0){
printf("You may take test %d directly.\n", ed);
}else{
for(int i=path.size()-2; i>=0; i--){
printf("%d", path[i]);
if(i>0){
printf("->");
}else{
printf("\n");
}
}
}
path.clear();
tmpPath.clear();
}
}else{
printf("Impossible.\n");
for(int i=0; i<query; i++){
scanf("%d", &ed);
if(d[ed]==0){
printf("You may take test %d directly.\n", ed);
}else{
printf("Error.\n");
}
}
}
return 0;
}