今天运气不错,连a两道,在此再记录一下。(要是是这学期中能够找到这么多时间来写它就好了啊……悔不当初)
此题大意是说找到一群牛之间的满足差分约束关系下的最大值,那么按小于的标准建边跑最短路得到的就是最长路。算法导论这一章中讲到的是求一个差分约束的可行性问题,所以会多加一个点并将它作为源点来跑单源最短路径。这里是找到某一点的,所以不需多加那一个顶点,直接来跑SPFA即可。判断存在负环类似Bellman-Ford,找到它其中是否有一个点入队列多于n次就好(保险起见取n+1,反正多一次复杂度只是损失常数2333).另外发现应该多用类与结构的构造函数,帮我节省了许多代码空间。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 1003
#define INF 0x3f3f3f3f
int n, ml, md;
typedef struct Edge {
int nextNode;
int weight;
struct Edge (int v, int w) {nextNode = v;weight = w;}
}Edge;
typedef struct Vertex {
int nodeName;
int distance;
struct Vertex (int x, int dis) { nodeName = x; distance = dis; }
}Vertex;
class RestraintGraph
{
public:
void init(int size)
{
for (int i = 0; i < size ; i++)
edges[i].clear();
while (vertices.empty() == false)
vertices.pop();
memset(verticesInQueue, 0, sizeof(verticesInQueue));
memset(verticesInQueueTimes, 0, sizeof(verticesInQueueTimes));
vertex.clear();
for (int i = 0; i < size ; i++)
vertex.push_back(INF);
}
void input()
{
int cow1, cow2, dis;
for (int i = 0; i < ml; i++) {
scanf("%d %d %d", &cow1, &cow2, &dis);
_addEdge(cow1-1, cow2-1, dis);
}
for (int i = 0; i < md; i++) {
scanf("%d %d %d", &cow1, &cow2, &dis);
_addEdge(cow2-1 , cow1-1 , -dis);
}
for (int i = 0; i < n - 1 ; i++)
_addEdge(i+1, i, 0);
}
void SPFA(int s)
{
Vertex ss = Vertex(s, 0);
vertex[s] = 0;
vertices.push(ss);
verticesInQueue[s] = true;
verticesInQueueTimes[s]++;
bool canSolve = true;
while (vertices.empty() == false&&canSolve) {
Vertex u = vertices.front();
vertices.pop();
int uu = u.nodeName,vv;
verticesInQueue[uu] = false;
for (int i = 0; i < edges[uu].size(); i++) {
vv = edges[uu][i].nextNode;
if (vertex[vv] > vertex[uu] + edges[uu][i].weight) {
vertex[vv] = vertex[uu] + edges[uu][i].weight;
if (!_check(vv)) {
vertices.push(Vertex(vv, 0));
verticesInQueueTimes[vv]++;
if (verticesInQueueTimes[vv] > n + 1)
canSolve = false;
_set(vv);
}
}
}
}
if (canSolve)
printf("%d\n", vertex[n - 1] == INF ? -2 : vertex[n - 1]);
else
printf("-1\n");
}
private:
vector edges[MAXN];
vector vertex;
queue vertices;
bool verticesInQueue[MAXN];
int verticesInQueueTimes[MAXN];
void _addEdge(int u, int v, int w){ edges[u].push_back(Edge(v,w));}
bool _check(int v) { return verticesInQueue[v]; }
void _set(int v) { verticesInQueue[v] == true; }
};
int main()
{
RestraintGraph rg;
while (scanf("%d %d %d", &n, &ml, &md) != EOF) {
rg.init(n);
rg.input();
rg.SPFA(0);
}
return 0;
}