zoukankan      html  css  js  c++  java
  • Instrction Arrangement UDH 4109 拓扑排序 or 最长路

    题目描述

    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.

    分析

    这道题至少有两种方法

    拓扑排序

    第一种方法就是拓扑排序
    显然没有任何约束的指令可以在第一秒同时执行。
    对有一个或多个约束指令我们要满足最远的那个约束之后
    定义dp[i],表示执行指令i的最早时间,则有:dp[i]=max(dp[i],dp[j]+a[j][i]),a[j][i]表示i必须在j执行后a[j][i]秒后执行。
    临界没有任何约束的指令在第一秒时执行,dp[]=1
    阶段很明显,当前入度为0点,下个阶段为这些点的临界点。

    代码

    #include <bits/stdc++.h>
    const int maxn=1000+5,maxm=1e4+5;
    struct Node{int to;int dis;int next;}e[maxm];
    int n,m,len,head[maxn],rd[maxn],dp[maxn];
    void Insert(int x,int y,int z){
        e[++len].to=y;e[len].dis=z;e[len].next=head[x];head[x]=len;
    }
    void Kahn(){
        std::stack<int> q;
        for(int i=0;i<n;++i){
            if(!rd[i])q.push(i),dp[i]=1;
            else dp[i]=0;
        }
        int ans=1; 
        while(!q.empty()){
            int u=q.top();q.pop();
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].to,w=e[i].dis;rd[v]--;
                dp[v]=std::max(dp[v],dp[u]+w);
    			ans=std::max(ans,dp[v]); 
                if(!rd[v])q.push(v);
            }
        }
        printf("%d
    ",ans);
    }
    void Solve(){
    	while(scanf("%d%d",&n,&m)!=EOF){
    		memset(head,0,sizeof(head));
    		memset(rd,0,sizeof(rd));
    		len=0;
    		for(int i=1;i<=m;++i){
            	int x,y,z;scanf("%d%d%d",&x,&y,&z);
            	Insert(x,y,z);rd[y]++;
        	}    
        	Kahn();
    	}    
    }
    int main(){
        Solve();
        return 0;
    }
    

    最长路

    其实细细思考一下,建一个超级源点跑最长路也是可以的

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    const int maxd=1005,maxb=20005;
    int ru[maxd],chu[maxd];
    int head[maxd],tot=1;
    int n,m;
    struct asd{
        int from,to,next,val;
    }b[maxb];
    void ad(int aa,int bb,int cc){
        b[tot].from=aa;
        b[tot].to=bb;
        b[tot].next=head[aa];
        b[tot].val=cc;
        head[aa]=tot++;
    }
    bool vis[maxd];
    int dis[maxd];
    void SPFA(){
        queue<int> q;
        q.push(n);
        for(int i=0;i<maxd;i++){
    		dis[i]=-0x3f3f3f3f;
    	}
        dis[n]=0;
        while(!q.empty()){
            int xx=q.front();
            q.pop();
            vis[xx]=0;
            for(int i=head[xx];i!=-1;i=b[i].next){
                int u=b[i].to;
                if(dis[u]<dis[xx]+b[i].val){
                    dis[u]=dis[xx]+b[i].val;
                    if(!vis[u])q.push(u),vis[u]=1;
                }
            }
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        memset(&b,0,sizeof(struct asd));
        memset(ru,0,sizeof(ru));
        memset(chu,0,sizeof(chu));
        tot=1;
        for(int i=1;i<=m;i++){
            int aa,bb,cc;
            scanf("%d%d%d",&aa,&bb,&cc);
            ad(aa,bb,cc);
            ru[bb]++;
            chu[aa]++;
        }
        for(int i=0;i<n;i++){
            if(ru[i]==0){
                ad(n,i,1);
            }
        }
        SPFA();
        int ans=1;
        for(int i=0;i<n;i++){
            ans=max(ans,dis[i]);
        }
        printf("%d
    ",ans);
    	}
        return 0;
    }
    
  • 相关阅读:
    A20 烧录和启动 log
    图像处理---图像分割技术---基于图像灰度分布的阈值方法一
    H.265---内容总览
    H.265---仿射运动模型和双线性运动模型
    H.265---帧内预测与帧间预测
    linux内核---进程通信---消息队列
    linux内核---嵌入式linux内核的五个子系统
    高并发服务器---nginx---实现负载均衡的几种方式
    高并发服务器---nginx---正向代理和反向代理
    【CV系列】基于形态学梯度的边缘检测
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12814319.html
Copyright © 2011-2022 走看看