现在的位置: 首页 > 综合 > 正文

HDU 4109 Instrction Arrangement

2013年10月11日 ⁄ 综合 ⁄ 共 2333字 ⁄ 字号 评论关闭

 

题意:给你一些机器指令,某些有先后顺序(若A->B,C->B则必须A、C执行完才能执行B),且有安全距离(若A->B 距离n)那么必须在从A执行算起n时间,才能执行B,一次可以运行多个指令,指令的完成只花费1,最后求执行完所有指令所需的最短的时间。

思想:求到达各点的最大值(所有能到达该点的花费的最大值)的最大值(即所有点的最大值)。

解法:①纯递归搜索:这是最简单直观的做法,从入度为0点开始搜索,记录每点的最大值,最后求所有点的最大值即可。

            ② “最短路算法”求解:你可以直接求所有点的最长路或者是反向建图求最短路 ,最后找最长的或者最短的(注意负数)。

            ③用拓扑排序的思想也可求解。

 这么所方法其实都一样,代码的实现可能与叙述有所不同,但思想绝对一样!

①的代码:

#include <stdio.h>
#include <string.h>

#define N 1002
#define M 10002

int nodev[N];
int nodeu[M],value[M],next[M];
int indegree[N];

void Build_Graph(int m)
{
    int i,v,u,val,ind;

    memset(indegree,0,sizeof(indegree));
    memset(nodev,-1,sizeof(nodev)); ind=0;
    for(i=0;i<m;i++)
    {
        scanf("%d %d %d",&v,&u,&val);
        
        indegree[u]++;
        nodeu[ind]=u;
        value[ind]=val;
        next[ind]=nodev[v];
        nodev[v]=ind;
        ind++;
    }
}

int record[N];
int DFS(int v)
{
    int i,u,val;
    
    if(record[v]!=0)
    {
        return record[v];
    }
    
    for(i=nodev[v];i!=-1;i=next[i])
    {
        u=nodeu[i];
            
        val=DFS(u);
        if(val+value[i]>record[v])
            record[v]=val+value[i];
    }
    return record[v];
}

void solve()
{
    int v,n,m,temp,max;

    while(scanf("%d %d",&n,&m)!=EOF)
    {
        Build_Graph(m);

        memset(record,0,sizeof(record)); max=0;
        for(v=0;v<n;v++)
        {
            if(indegree[v]==0)
            {
                temp=DFS(v);
                if(temp>max) max=temp;
            }
        }
        printf("%d\n",max+1);
    }
}

int main()
{
    solve();
    return 0;
}

②思想的代码:

#include <stdio.h>
#include <string.h>

#define N 1002
#define M 10002
#define MOVE(x) (x=(x+1)%N)
#define MAXVAL 0xfffffff

int S,E; //添加的源点,终点

int nodev[N];
int nodeu[M+N*2],value[M+N*2],next[M+N*2],ind;
void addedge(int v,int u,int val)
{
	nodeu[ind]=u;
	value[ind]=val;
	next[ind]=nodev[v];
	nodev[v]=ind;
	ind++;
}
void Build_Graph(int n,int m)
{
	int i,v,u,val;
	
	memset(nodev,-1,sizeof(nodev)); 
	S=0; E=n+1; ind=0;

	for(i=0;i<m;i++)
	{
		scanf("%d %d %d",&v,&u,&val);
		v++;	u++;	val=-val;
		addedge(u,v,val);
	}
	for(i=1;i<=n;i++)
	{
		addedge(S,i,0);
		addedge(i,E,0);
	}
}

int queue[N],dist[N];
bool flag[N];
void SPFA(int s,int n)
{
	int i,v,u,val;
	int front,rear;

	for(i=1;i<=n+1;i++)	dist[i]=MAXVAL; 
	dist[s]=0;//当S加入队列时,一定有负环,但有负环,不一定是S一定要进队列!!
	memset(flag,false,sizeof(flag));
	front=-1;	rear=-1;
	queue[MOVE(rear)]=s;	flag[s]=true;
	//可不要
//	for(i=nodev[s];i!=-1;i=next[i])
//	{
//		u=nodeu[i];	val=value[i];
//		dist[u]=val;	
//		queue[MOVE(rear)]=u; flag[u]=true;
//	}

	while(front!=rear)
	{
		v=queue[MOVE(front)]; flag[v]=false;
		for(i=nodev[v];i!=-1;i=next[i])
		{
			u=nodeu[i]; val=value[i];
			if(dist[v]+val<dist[u])
			{
				dist[u]=dist[v]+val;
				if(!flag[u])
				{
					queue[MOVE(rear)]=u;
					flag[u]=true;
				}
			}
		}
	}
}

void solve()
{
	int n,m;
	
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		Build_Graph(n,m);
		SPFA(S,n);
		printf("%d\n",1-dist[E]);
	}
}

int main()
{
	solve();
	return 0;
}

 

 

抱歉!评论已关闭.