NOIP2009 提高第三题 最佳贸易

来源:互联网 发布:京东秒杀软件 编辑:程序博客网 时间:2024/05/16 11:55

NOIP2009 提高第三题 最佳贸易
2017年7月14日
双向SPFA


#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;/*第一行包含 2 个正整数 n 和 m,中间用一个空格隔开,分别表示城市的数目和道路的数目。第二行 n 个正整数,每两个整数之间用一个空格隔开,按标号顺序分别表示这 n 个城市的商品价格。接下来 m 行,每行有 3 个正整数,x,y,z,每两个整数之间用一个空格隔开。如果 z=1,表示这条道路是城市 x 到城市 y 之间的单向道路;如果 z=2,表示这条道路为城市 x 和城市y 之间的双向道路。*/const int maxx1 = 110000, maxx2 = 500100;int N, M;//分别表示城市的数目和道路的数目;// 1≤n≤100000,1≤m≤500000;int price[maxx1];//正向SPFAstruct Edge_1{    int y;  int next;}F1[maxx2];int L1[maxx1];//反向SPFAstruct Edge_2{    int y;  int next;}F2[maxx2];int L2[maxx1];int tails1 = 0;int tails2 = 0;//int minDis[maxx1];int maxDis[maxx1];bool Jud[maxx1];//Wholeint Que[maxx1];//Wholeint ans = 0, ed = 1;//wholevoid Getinto(int a, int b){    F1[++tails1].y = b;    F1[tails1].next = L1[a];    L1[a] = tails1;    //    F2[++tails2].y = a;    F2[tails2].next = L2[b];    L2[b] = tails2;}void Putin(){    cin >> N >> M;    memset(F1, 0, sizeof(F1));    memset(F2, 0, sizeof(F2));    for(int i = 1; i <= N; i++)        cin >> price[i];    int xi, yi, zi;    for(int i = 1; i <= M; i++){        cin >> xi >> yi >> zi;        if(zi == 1)     Getinto(xi, yi);        else{            Getinto(xi, yi);            Getinto(yi, xi);        }    }    return;}void stSPFA(){    memset(minDis, 10, sizeof(minDis));    memset(Que, -1, sizeof(Que));    memset(Jud, false, sizeof(Jud));    Que[1] = 1;     Jud[1] = true;      minDis[1] = price[1];    while(ans <= ed)    {        int sgn = Que[++ans];     Jud[sgn] = false;        int lne = L1[sgn];        //sng:队头节点;     lne:sng节点的每条边;        for(int i = lne; i; i = F1[i].next)        {            int wto = F1[i].y;//指向的节点;            if(minDis[wto] > min(minDis[sgn], price[wto])){                minDis[wto] = min(minDis[sgn], price[wto]);                if(Jud[wto] == false){                    Que[++ed] = wto;                    Jud[wto] = true;                }            }        }    }    return;}void enSPFA(){    memset(Que, -1, sizeof(Que));    memset(Jud, false, sizeof(Jud));    memset(maxDis, -1, sizeof(maxDis));    ans = 0;    ed = 1;    maxDis[N] = price[N];   Que[1] = N;    Jud[N] = true;    while(ans <= ed)    {        int sgn = Que[++ans];   Jud[sgn] = false;        int lne = L2[sgn];        //sng:队头节点;     lne:sng节点的每条边;        for(int i = lne; i; i = F2[i].next)        {            int wto = F2[i].y;            if(maxDis[wto] < max(maxDis[sgn], price[wto]))            {                maxDis[wto] = max(maxDis[sgn], price[wto]);                if(Jud[wto] == false){                    Que[++ed] = wto;                    Jud[wto] = true;                }            }        }    }    return;}void Find(){    int maxans = -1;//城市最大差价    for(int i = 1; i <= N; i++)    {        if(maxDis[i] == -1 || minDis[i] > 1000)            continue;        maxans = max(maxans, (maxDis[i] - minDis[i]));    }    if(maxans <= 0)     cout << 0 << endl;    else    cout << maxans <<endl;}int main(){    Putin();    stSPFA();    enSPFA();    Find();    return 0;}
原创粉丝点击