UVa1112
来源:互联网 发布:西门子仿真软件 编辑:程序博客网 时间:2024/06/04 19:00
题意:给出n个点和m个边及起始点(相当于此问题中的出口点),求从起始点可到达的点的个数
思路:因为出口点为从其它点通过一些边后到达的终点,因此在添加边关系时,起点转为终点,终点转为起点。
代码如下:
#include<iostream>#include <vector>#include <queue>#include <set>#include <fstream>#include <cstring>using namespace std;const int N = 110;const int INF = 0x3fffffff;class Solution{public:void init(int n, int e, int t){this->n = n;this->e = e;this->t = t;for (int i = 0; i < n; i++) adjList[i].clear();edges.clear();}void addEdge(int u, int v, int t){Edge edge = {v, u, t};edges.push_back(edge);int size = edges.size();adjList[v - 1].push_back(size - 1);}int dijkstra(int s){for (int i = 0; i < n; i++){d[i] = INF;}d[s - 1] = 0;priority_queue<HeapNode> pq;pq.push({0, s - 1});set<int> done;while (!pq.empty()){HeapNode curNode = pq.top(); pq.pop();if (done.count(curNode.u)) continue;done.insert(curNode.u);int u = curNode.u;for (size_t i = 0; i < adjList[u].size(); i++){Edge& e = edges[adjList[u][i]];if (d[e.from - 1] + e.cost < d[e.to - 1] && d[e.from - 1] + e.cost <= t){d[e.to - 1] = d[e.from - 1] + e.cost;pq.push({d[e.to - 1], e.to - 1});}}}int cnt = 0;for (int i = 0; i < n; i++){if (d[i] != INF) cnt++;}return cnt;}private:class Edge{public:int from, to, cost;};class HeapNode{public:int d, u;bool operator < (const HeapNode& other) const{return d > other.d;}};private:int n, e, t;vector<Edge> edges;vector<int> adjList[N];int d[N];};int main(){Solution solver;int cases;#ifndef ONLINE_JUDGEifstream fin("f:\\OJ\\uva_in.txt");streambuf* old = cin.rdbuf(fin.rdbuf());#endifcin >> cases;while (cases--){int n, e, t, m;cin >> n >> e >> t;solver.init(n, e, t);cin >> m;while (m--){int u, v, t;cin >> u >> v >> t;solver.addEdge(u, v, t);}int cnt = solver.dijkstra(e);cout << cnt << endl;if (cases) cout << endl;}#ifndef ONLINE_JUDGEcin.rdbuf(old);#endifreturn 0;}
floyd_warshall算法实现如下:
#include <cstdio>#include <fstream>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 110;const int INF = 0x3fffffff;class Solution{public: void init(int n, int e, int t) { this->n = n; this->e = e; this->t = t; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i != j) f[i][j] = INF; else f[i][j] = 0; } } } void addEdge(int u, int v, int t) { f[u - 1][v - 1] = t; } int floyd_warshall() { memcpy(dp, f, sizeof(f)); for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (dp[i][k] != INF && dp[k][j] != INF) { dp[i][j] = min(dp[i][k] + dp[k][j], dp[i][j]); } } } } int ans = 0; for (int i = 0; i < n; i++) { if (dp[i][e - 1] <= t) { ans++; } } return ans; }private: int n, e, t; int f[N][N]; int dp[N][N];};int main(){#ifndef ONLINE_JUDGE ifstream fin("D:\\program\\clion\\spoj.txt"); streambuf* old = cin.rdbuf(fin.rdbuf());#endif Solution solver; int cases; cin >> cases; while (cases--) { int n, e, t, m; cin >> n >> e >> t; solver.init(n, e, t); cin >> m; while (m--) { int u, v, t; cin >> u >> v >> t; solver.addEdge(u, v, t); } int ans = solver.floyd_warshall(); cout << ans << endl; if (cases) cout << endl; }#ifndef ONLINE_JUDGE cin.rdbuf(old);#endif return 0;}