HDU 4109 Instrction Arrangement 差分约束系统

本文探讨了在存在指令依赖关系的情况下如何通过增加空操作来确保指令间的最小安全距离,从而避免潜在的冲突并达到优化CPU执行时间的目的。利用差分约束系统进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Instrction Arrangement

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 107 Accepted Submission(s): 48


Problem Description
Ali has taken the Computer Organization and Architecture course this term. He learned that there may be dependence between instructions, like WAR (write after read), WAW, RAW.
If the distance between two instructions is less than the Safe Distance, it will result in hazard, which may cause wrong result. So we need to design special circuit to eliminate hazard. However the most simple way to solve this problem is to add bubbles (useless operation), which means wasting time to ensure that the distance between two instructions is not smaller than the Safe Distance.
The definition of the distance between two instructions is the difference between their beginning times.
Now we have many instructions, and we know the dependent relations and Safe Distances between instructions. We also have a very strong CPU with infinite number of cores, so you can run as many instructions as you want simultaneity, and the CPU is so fast that it just cost 1ns to finish any instruction.
Your job is to rearrange the instructions so that the CPU can finish all the instructions using minimum time.

Input
The input consists several testcases.
The first line has two integers N, M (N <= 1000, M <= 10000), means that there are N instructions and M dependent relations.
The following M lines, each contains three integers X, Y , Z, means the Safe Distance between X and Y is Z, and Y should run after X. The instructions are numbered from 0 to N - 1.

Output
Print one integer, the minimum time the CPU needs to run.

Sample Input
  
5 2 1 2 1 3 4 1

Sample Output
  
2
Hint
In the 1st ns, instruction 0, 1 and 3 are executed; In the 2nd ns, instruction 2 and 4 are executed. So the answer should be 2.

Source

Recommend
lcy
 
差分约束系统
加一个源点s指向所有点边权为0,
加一个汇点t,所有点指向t边权为0,
u和v安全距离为w,则加边v->u,边权为-w
求s到t最短路即可。
代码:
#include<cstdio>
#include<cstring>
#define N 1005

int n,m,num,adj[N],low[N],f[N],q[N];
struct edge
{
	int v,w,pre;
}e[N*10];
void insert(int u,int v,int w)
{
	e[num].v=v;
	e[num].w=w;
	e[num].pre=adj[u];
	adj[u]=num++;
}
void spfa(int x)
{
	int i,v,head=0,tail=0;
	memset(f,0,sizeof(f));
	memset(low,0x3f,sizeof(low));
	low[x]=0;
	q[++tail]=x;
	while(head!=tail)
	{
		x=q[head=(head+1)%N];
		f[x]=0;
		for(i=adj[x];~i;i=e[i].pre)
			if(low[v=e[i].v]>low[x]+e[i].w)
			{
				low[v]=low[x]+e[i].w;
				if(!f[v])
				{
					f[v]=1;
					q[tail=(tail+1)%N]=v;
				}
			}
	}
}
int main()
{
	int u,v,w;
	while(~scanf("%d%d",&n,&m))
	{
		num=0;
		memset(adj,-1,sizeof(adj));
		while(m--)
		{
			scanf("%d%d%d",&u,&v,&w);
			u++;v++;
			insert(v,u,-w);
		}
		for(u=1;u<=n;u++)
		{
			insert(0,u,0);
			insert(u,n+1,0);
		}
		spfa(0);
		printf("%d\n",1-low[n+1]);
	}
}

HDU 4109是一道经典的算法题目,题目名称为“Agent J”。这道题目主要考察的是图论中的最短路径算法,特别是Dijkstra算法的应用。 题目描述: 在一个有向图中,给定起点和终点,求从起点到终点的最短路径。如果存在多条最短路径,输出字典序最小的路径。 解题思路: 1. 使用Dijkstra算法计算从起点到终点的最短路径。 2. 在Dijkstra算法的基础上,使用优先队列来确保找到的路径字典序最小。 3. 使用一个数组来记录每个节点的前驱节点,以便最后可以回溯出完整的路径。 代码实现: ```java import java.util.*; public class Main { static class Edge { int to, weight; Edge(int to, int weight) { this.to = to; this.weight = weight; } } static class Node implements Comparable<Node> { int id, dist; Node(int id, int dist) { this.id = id; this.dist = dist; } @Override public int compareTo(Node other) { return this.dist - other.dist; } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int T = scanner.nextInt(); while (T-- > 0) { int n = scanner.nextInt(); int m = scanner.nextInt(); List<List<Edge>> graph = new ArrayList<>(); for (int i = 0; i <= n; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int from = scanner.nextInt(); int to = scanner.nextInt(); int weight = scanner.nextInt(); graph.get(from).add(new Edge(to, weight)); } int start = scanner.nextInt(); int end = scanner.nextInt(); int[] dist = new int[n + 1]; Arrays.fill(dist, Integer.MAX_VALUE); dist[start] = 0; int[] prev = new int[n + 1]; Arrays.fill(prev, -1); PriorityQueue<Node> pq = new PriorityQueue<>(); pq.offer(new Node(start, 0)); while (!pq.isEmpty()) { Node current = pq.poll(); if (current.id == end) break; if (current.dist > dist[current.id]) continue; for (Edge edge : graph.get(current.id)) { if (dist[edge.to] > current.dist + edge.weight) { dist[edge.to] = current.dist + edge.weight; prev[edge.to] = current.id; pq.offer(new Node(edge.to, dist[edge.to])); } else if (dist[edge.to] == current.dist + edge.weight && prev[edge.to] > current.id) { prev[edge.to] = current.id; } } } if (dist[end] == Integer.MAX_VALUE) { System.out.println(-1); } else { List<Integer> path = new ArrayList<>(); int current = end; while (current != -1) { path.add(current); current = prev[current]; } Collections.reverse(path); for (int i = 0; i < path.size(); i++) { System.out.print(path.get(i) + (i < path.size() - 1 ? " " : "\n")); } } } scanner.close(); } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值