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;
    }
    
  • 相关阅读:
    java表达式中运算符优先级
    数据库建表规则
    linux 安装java环境
    springboot指定端口的三种方式
    服务器监控
    Dubbo 的配置主要分为三大类
    oracle数值函数 abs()、 ceil()、 cos()、 cosh()
    linux基础命令总结
    redis+sentinel集群部署
    centos7制作本地yum源
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12814319.html
Copyright © 2011-2022 走看看