您的位置:首页 > 其它

POJ3259-Wormholes

2014-07-30 21:04 288 查看
转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299075341

提示:

利用虫洞的时光旅行,很有趣的一道题。涉及到图论的知识,关键是构造图,用Bellman-Ford算法找出负权环

Bellman-Ford算法核心在于松弛,具体可以百度,这里就不重复前人的智慧了O(∩_∩)O哈哈~

需要注意的就是输入说明[b]Input这部分,很多人读不懂这段题意:[/b]

正权(双向)边部分:

Line 1 of each farm: Three space-separated integers respectively: N, M, and W

Lines 2~M+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: a bidirectional path between S and E that requires Tseconds to traverse.

Two fields might be connected by more than one path.



负权(单向)边部分:

Lines M+2~M+W+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.

/** \brief poj3259
 *
 * \param date 2014/7/30
 * \param state AC
 * \return memory 744K time 500ms
 *
 */

#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

const int MAX_W=10001;//无穷远
int dis[1001];//源点到各点权值

class weight
{
public:
    int s;
    int e;
    int t;
}edge[5200];

//N (1≤N≤500)fields 顶点数
//M (1≤M≤2500)paths 正权双向边
//W_h (1≤W≤200) wormholes 虫洞(回溯,负权单向边
int N,M,W_h;
int all_e; //边集(边总数)

bool bellman()
{
    bool flag;
    memset(dis,MAX_W,sizeof(dis));//源点到各点的初始值为无穷,即默认不连通
    /*relax*/
    for(int i=0;i<N-1;i++)
    {
        flag=false;
        for(int j=0;j<all_e;j++)
            if(dis[edge[j].e] > dis[edge[j].s]+edge[j].t)
            {
                dis[edge[j].e] = dis[edge[j].s]+edge[j].t;
                flag=true;//relax对路径有更新
            }
        //只要某一次relax没有更新,说明最短路径已经查找完毕,
        //或者部分点不可达,可以跳出relax
        if(!flag)break;
    }
    /*Search Negative Circle*/
    for(int k=0;k<all_e;k++)
        if(dis[edge[k].e] > dis[edge[k].s]+edge[k].t)
        return true;

    return false;
}
int main()
{
    //cout << "Hello world!" << endl;
    //freopen("input.txt","r",stdin);
    int u,v,w;
    int F;
    cin>>F;
    while(F--)
    {

        cin>>N>>M>>W_h;
        all_e=0;//初始化指针
        /*read in Positive Paths*/
        for(int i=1;i<=M;i++)
        {
            cin>>u>>v>>w;
            //由于paths的双向性,两个方向权值相等,注意指针的移动
            edge[all_e].s=edge[all_e+1].e=u;
            edge[all_e].e=edge[all_e+1].s=v;
            edge[all_e++].t=w;
            edge[all_e].t=w;
            all_e++;
        }
        /*read in Negative Wormholds*/
        for(int j=1;j<=W_h;j++)
        {
            cin>>u>>v>>w;
            edge[all_e].s=u;
            edge[all_e].e=v;
            edge[all_e++].t=-w;//注意权值为负
        }
        /*Bellman-Ford Algorithm*/
        if(bellman())
            cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}






[cpp] view
plaincopy

//Memory Time

//308K 204MS



#include<iostream>

using namespace std;



int dis[1001]; //源点到各点权值

const int max_w=10001; //无穷远



class weight

{

public:

int s;

int e;

int t;

}edge[5200];



int N,M,W_h; //N (1≤N≤500)fields 顶点数

//M (1≤M≤2500)paths 正权双向边

//W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边

int all_e; //边集(边总数)



bool bellman(void)

{

bool flag;



/*relax*/



for(int i=0;i<N-1;i++)

{

flag=false;

for(int j=0;j<all_e;j++)

if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)

{

dis[edge[j].e] = dis[edge[j].s] + edge[j].t;

flag=true; //relax对路径有更新

}

if(!flag)

break; //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax

}



/*Search Negative Circle*/



for(int k=0;k<all_e;k++)

if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)

return true;



return false;

}

int main(void)

{

int u,v,w;



int F;

cin>>F;

while(F--)

{

memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通



cin>>N>>M>>W_h;



all_e=0; //初始化指针



/*read in Positive Paths*/



for(int i=1;i<=M;i++)

{

cin>>u>>v>>w;

edge[all_e].s=edge[all_e+1].e=u;

edge[all_e].e=edge[all_e+1].s=v;

edge[all_e++].t=w;

edge[all_e++].t=w; //由于paths的双向性,两个方向权值相等,注意指针的移动

}



/*read in Negative Wormholds*/



for(int j=1;j<=W_h;j++)

{

cin>>u>>v>>w;

edge[all_e].s=u;

edge[all_e].e=v;

edge[all_e++].t=-w; //注意权值为负

}



/*Bellman-Ford Algorithm*/



if(bellman())

cout<<"YES"<<endl;

else

cout<<"NO"<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: