POJ_3259题解

来源:互联网 发布:淘宝卖家工具大全 编辑:程序博客网 时间:2024/05/14 01:58

题目大意:

        有个人捏,他捏,没错,他捏就叫Farmer John(POJ经常有他的身影),有一天捏,FJ捏在他家农场里捏发现了许多虫洞,这些虫洞是单向的,能将你送到某一地点,并且具有时间倒流的能力。FJ就想能不能通过这些虫洞和一些双向路径达到让自己时光倒流的目的。


输入:

2               //农场个数

3 3 1        //田地    路径    虫洞    分别的个数

1 2 2       //田地路径    起点     终点    权值

1 3 4

2 3 1

3 1 3     //虫洞路径    起点   终点     权值(记得,事实上市负的)

3 2 1

2 3 4

3 1 8


思路:用Bellman松弛N次看有无负环,第一次用Bellman,所以我把有负权值的路径更新为负的。

 

之前发表过一篇耗时1688ms的(已删),后来发现有好多多余操作,更改后代码如下:


//Memory:268K             Time:79ms#include<cstdio>#include<iostream>#include<cstring>struct Edge            //边{int u,v,weight;}edge[10020];int dis[10100];        //用于记录离源点距离int nodenum,edgenum,sourcenum;void relax(int u,int v,int w)   //松弛操作函数{if(dis[v]>dis[u]+w)dis[v]=dis[u]+w;}int main(){int f,a,b,c;scanf("%d",&f);while(f--){bool flag;flag=0;scanf("%d%d%d",&nodenum,&edgenum,&sourcenum);edgenum*=2;             //双向边,故乘以2for(int i=1;i<=edgenum;i+=2)                //建立双向边{scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].weight);edge[i+1].u=edge[i].v;edge[i+1].v=edge[i].u;edge[i+1].weight=edge[i].weight;}for(int i=1;i<=sourcenum;i++)         //建立单向边{scanf("%d%d%d",&a,&b,&c);edgenum++;edge[edgenum].u=a;edge[edgenum].v=b;edge[edgenum].weight=c*-1;       //权值是负的}memset(dis,0x3f,sizeof dis);dis[1]=0;for(int j=1;j<=edgenum;j++)    //初始化起点是1的边的离起点的距离disif(edge[j].u==1)dis[edge[j].v]=edge[j].weight;for(int p=1;p<nodenum;p++)           //进行n-1次松弛操作for(int q=1;q<=edgenum;q++)relax(edge[q].u,edge[q].v,edge[q].weight);for(int k=1;k<=edgenum;k++)          //第n次松弛操作,若还可松弛,则存在负环if(dis[edge[k].v]>dis[edge[k].u]+edge[k].weight){flag=1;break;}if(flag)                printf("YES\n");            else printf("NO\n");}}

原创粉丝点击