最短路:HDU1839

博客围绕时延约束最大容量路径问题展开,给定无向图,包含顶点、边及边的容量和旅行时间。需找到从矿场到工厂的路径,使路径容量最大且总旅行时间不超给定值。还给出输入输出格式及示例,最后提及用二分下限加最短路求解。

 

Delay Constrained Maximum Capacity Path

Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2558    Accepted Submission(s): 887


 

Problem Description

Consider an undirected graph with N vertices, numbered from 1 to N, and M edges. The vertex numbered with 1 corresponds to a mine from where some precious minerals are extracted. The vertex numbered with N corresponds to a minerals processing factory. Each edge has an associated travel time (in time units) and capacity (in units of minerals). It has been decided that the minerals which are extracted from the mine will be delivered to the factory using a single path. This path should have the highest capacity possible, in order to be able to transport simultaneously as many units of minerals as possible. The capacity of a path is equal to the smallest capacity of any of its edges. However, the minerals are very sensitive and, once extracted from the mine, they will start decomposing after T time units, unless they reach the factory within this time interval. Therefore, the total travel time of the chosen path (the sum of the travel times of its edges) should be less or equal to T.

 

 

Input

The first line of input contains an integer number X, representing the number of test cases to follow. The first line of each test case contains 3 integer numbers, separated by blanks: N (2 <= N <= 10.000), M (1 <= M <= 50.000) and T (1 <= T <= 500.000). Each of the next M lines will contain four integer numbers each, separated by blanks: A, B, C and D, meaning that there is an edge between vertices A and B, having capacity C (1 <= C <= 2.000.000.000) and the travel time D (1 <= D <= 50.000). A and B are different integers between 1 and N. There will exist at most one edge between any two vertices.

 

 

Output

For each of the X test cases, in the order given in the input, print one line containing the highest capacity of a path from the mine to the factory, considering the travel time constraint. There will always exist at least one path between the mine and the factory obbeying the travel time constraint.

 

 

Sample Input


 

2 2 1 10 1 2 13 10 4 4 20 1 2 1000 15 2 4 999 6 1 3 100 15 3 4 99 4

 

 

Sample Output


 

13

99

 

很简单的二分下限+最短路

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN=100005;
const long long INF=1ll << 60;
int n, m, time;
struct qnode{
	int v;
	long long c;
	qnode(int _v=0,long long _c = 0):v(_v),c(_c){}
	bool operator <(const qnode &r)const{
		return c > r.c;
	}
};
struct Edge{
	int v;
	long long c;
	int d;
	Edge(int _v=0,long long _c=0, int _d = 0):v(_v),c(_c),d(_d){}
};
vector<Edge>E[MAXN];
bool vis[MAXN];
long long dist[MAXN];
long long c[5*MAXN];
long long cons;
void Dijkstra(int n,int start){
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=n;i++) dist[i]=INF;
	priority_queue<qnode>que;
	while(!que.empty()) que.pop();
	dist[start]=0;
	que.push(qnode(start,0));
	qnode tmp;
	while(!que.empty()){
		tmp=que.top();
		que.pop();
		int u=tmp.v;
		if(vis[u])continue;
		vis[u]=true;
		for(int i = 0; i < E[u].size(); i++){
			int v = E[u][i].v;
			if(dist[v] > dist[u] + E[u][i].d && E[u][i].c >= cons)
			{
				dist[v] = dist[u] + E[u][i].d;
				que.push(qnode(v,dist[v]));
			}
		}
	}
}
void addedge(int u,int v,long long w1, int w2){
	E[u].push_back(Edge(v,w1, w2));
}
int main()
{
	//freopen("test2.in","w",stdout);
	int T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d", &n, &m, &time);
		for(int i = 0; i <= n; i++) E[i].clear();
		memset(c, 0, sizeof(c));
		for(int i = 0; i < m; i++)
		{
			int u, v;
			long long c1;
			int d1;
			scanf("%d%d%lld%d", &u, &v, &c1, &d1);
			addedge(u, v, c1, d1);
			addedge(v, u, c1, d1);
			c[i] = c1;
		}
		sort(c, c+m);
		int l = 0, r = m - 1;
		long long ans = -1;
		while(l <= r)
		{
			int mid = (l + r) >> 1;
			cons = c[mid];
			Dijkstra(n, 1);
			if(dist[n] <= time)
			{
				ans = cons;
				l = mid + 1;
			}
			else r = mid - 1;
		}
		printf("%lld\n", ans);
	}
	return 0;
}
/*
5
4 6 20
1 2 10 2
1 3 20 13
1 4 11 30
2 3 30 5
2 4 5 8
3 4 50 9
*/

 

A-3 Linear Component 分数 25 作者 陈越 单位 浙江大学 A component of an undirected graph G is a maximum connected sub-graph of G. A linear component is a component that has a nonlinear structure property-- that is, each vertex in that component has exactly one or two previous vertex (except the first one), and one next vertex (except the last one). The size of a linear component is the number of edges plus vertices in the component. Now given an undirected graph, you are supposed to use assembly language find the largest size of its linear components. Input Specification: Each input file contains one test case, which first gives 2 positive integers: n (≤10 4 ), the number of vertices, and m (≤5n), the number of edges. Then m lines follow, each describes an edge in the form u v, where u and v are the indices of the two ends of the edge. The vertices are indexed from 1 to n. It is guaranteed that no duplicated edges are given. Output Specification: For each case, print in a line the number of vertices and the largest size of the linear components. Use variable dhjskycvi0 to store data. The numbers must be separated by a space. If there is no linear component, the maximum size is defined to be −1. Sample Input 1: 14 11 1 2 2 3 3 1 4 5 6 5 6 7 8 7 9 10 11 12 11 13 11 14 Sample Output 1: 2 4 Sample Input 2: 4 4 1 2 2 3 3 4 4 2 Sample Output 2: 0 -1 代码长度限制 16 KB Java (javac) 时间限制 1100 ms 内存限制 512 MB Python (python3) 时间限制 500 ms 内存限制 256 MB 其他编译器 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB c++题解
最新发布
07-23
在图论中,**大线性连通分量**通常是指图中具有长路径的连通分量,这通常出现在**有向无环图(DAG)**中,尤其是在**拓扑排序**的基础上进行动态规划处理以求解长路径的问题中。由于大线性连通分量的定义可能因上下文而异,以下将基于**长路径**的视角进行讨论,并提供一个基于拓扑排序和动态规划的C++实现方案。 ### 基本原理 对于一个**带权有向无环图(DAG)**,我们可以使用拓扑排序将图中的顶点线性排列,然后按照拓扑顺序对每个顶点进行动态规划计算,以找到从某个起点出发到该顶点的长路径长度。终,遍历所有顶点的长路径值即可确定整个图中大线性连通分量的长度。 ### 算法步骤 1. 对图进行拓扑排序。 2. 初始化一个`dp`数组,其中`dp[v]`表示从起点到顶点`v`的长路径长度。 3. 按照拓扑顺序遍历每个顶点,更新其邻接顶点的`dp`值。 4. 遍历结束后,`dp`数组中的大值即为长路径长度。 ### C++实现 ```cpp #include <iostream> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; class Graph { int V; vector<vector<pair<int, int>>> adj; public: Graph(int V) : V(V), adj(V) {} void addEdge(int u, int v, int weight) { adj[u].push_back({v, weight}); } void topologicalSortUtil(int v, vector<bool>& visited, stack<int>& Stack) { visited[v] = true; for (auto& neighbor : adj[v]) { int u = neighbor.first; if (!visited[u]) topologicalSortUtil(u, visited, Stack); } Stack.push(v); } void longestPath(int start) { vector<bool> visited(V, false); stack<int> Stack; for (int i = 0; i < V; ++i) if (!visited[i]) topologicalSortUtil(i, visited, Stack); vector<int> dp(V, INT_MIN); dp[start] = 0; while (!Stack.empty()) { int u = Stack.top(); Stack.pop(); if (dp[u] != INT_MIN) { for (auto& edge : adj[u]) { int v = edge.first; int weight = edge.second; if (dp[v] < dp[u] + weight) dp[v] = dp[u] + weight; } } } int maxLength = *max_element(dp.begin(), dp.end()); cout << "The length of the longest path is: " << maxLength << endl; } }; ``` ### 示例使用 ```cpp int main() { Graph g(6); g.addEdge(0, 1, 5); g.addEdge(0, 2, 3); g.addEdge(1, 3, 6); g.addEdge(1, 2, 2); g.addEdge(2, 4, 4); g.addEdge(2, 5, 2); g.addEdge(2, 3, 7); g.addEdge(3, 5, 1); g.addEdge(4, 5, -1); g.longestPath(0); return 0; } ``` ### 复杂度分析 - **时间复杂度**:O(V + E),其中 V 是顶点数,E 是边数。拓扑排序和动态规划过程均在线性时间内完成。 - **空间复杂度**:O(V),用于存储`dp`数组和栈结构。 ### 注意事项 - 该算法仅适用于**有向无环图(DAG)**,若图中存在环,则拓扑排序无法进行。 - 若图中存在负权边,该算法仍适用,但若存在正权环,则长路径问题可能无解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值