Vijos 1754 Best Trade _vijos

Source: Internet
Author: User
Describe

C state-owned N large cities and M road, each road connected to the N cities in some two cities. Any two
There is only one road between cities that is directly connected. Part of this m-path is a one-way road, part
For two-way roads, two-way roads are counted at 1 in the number of statistical bars.
C country A vast territory, the distribution of resources around the different, which led to the same commodity in the price of various cities
Lattice is not necessarily the same. However, the purchase price and the selling price of the same commodity in the same city are always the same.
Businessman Aaron came to C country to travel. When he learned that the price of the same commodity in different cities might be different this information
After that, they decided to make some travel money in the difference between the cities by using the goods at the same time. Set C Country N Cities
The label of the city from 1~ N, Aaron decided to start from the city of 1th, and eventually end their trip in N City. In the tourist
In the process, any city can be repeated many times, but not required to go through all n cities. Aaron through such a trade party
Type of travel: He will choose a city to buy his favorite commodity-crystal ball, and after the other
A city sells the crystal ball and uses the difference to make a trip. Since Aaron was mainly traveling to C, he decided
This trade is only done for the most of the time, and of course he does not have to trade without making any difference.
Assuming that C is 5 large cities, the number of cities and road connections are as follows, and one-way arrows indicate this road
For one-way traffic, the two-headed arrow indicates that the road is two-way traffic.

Suppose the crystal ball price of the city of 1~n is 4,3,5,6,1 respectively.
A-long can choose the following line: 1->2->3->5, and in the city of 2nd to buy 3 of the price of the crystal ball, in 3
The city sells the crystal ball at a price of 5 and earns 2 of its travel.
A-long can also choose the following line 1->4->5->4->5, and in the 1th time to reach the city of 5th at 1 price
Buy the crystal ball, in the 2nd time to the city of 4th to sell the crystal ball at 6 price, the number of travel to earn 5.

Now give the price of the crystal ball of N cities, the information of road m (number of two cities connected by each road)
And the passage of the road). Please tell Aaron how much he can earn for his trip. Format input Format

The first row contains 2 positive integers n and m, separated by a space between the number of cities and the road
Number.
The second row n positive integers, each two integers separated by a space, in the order of the label of the N city
Prices of commodities in the city.
Next to Line M, there are 3 positive integers per line, x, Y, Z, separated by a single space for each of the two integers. If Z=1,
Indicates that the road is a one-way road between City X and City y; if z=2, it means that the road is City X and City.
A two-way road between Y. Output format

The output is a total of 1 rows, and contains 1 integers, representing the maximum amount of travel that can be earned. If there is no trade,
The output is 0. Sample Example Input

5 5 
4 3 5 6 1 1 2 1 1 4 1 2 3 2 3 5 1 
 
Sample output
5
Limit

1s source per test point

Noip 2009




Think about learning Tarjan, then write a shrink point +DP

And then I loved it, and it exploded 0.

haha haha ha ha haha

You can't die without dying ...


Tarjan wrote it right, wrong in the DP.

At first, the insane from 1 recursive every point to the maximum value

Later found to have to stop to n

Which means you have to go to n when you've done business.

Which means that even the reverse side can go from N to the trading point.

So it's a DP ....


#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <cstdlib
> #include <algorithm> using namespace std;
const int lim=100011; struct Self{int x,y;}
S[LIM*10],K[LIM*10];
int firsts[lim*10],nxts[lim*10];
int firstk[lim*10],nxtk[lim*10];
int ss,kk;
int W[lim];
int Scc[lim],pre[lim],low[lim],maxv[lim],minv[lim];

int m,n,a,b,c,sccnt,dfstime,x,y,z;
stack<int>s;
    void Tarjan (int i) {dfstime++;
    Pre[i]=low[i]=dfstime;
    S.push (i);
            for (int e=firsts[i];e!=-1;e=nxts[e]) {if (!pre[s[e].y]) {Tarjan (S[E].Y);
        Low[i]=min (Low[i],low[s[e].y]);
    else if (!scc[s[e].y]) low[i]=min (Low[i],pre[s[e].y]);
        } if (Low[i]==pre[i]) {sccnt++;
        for (;;) {int x=s.top ();
            S.pop ();
            scc[x]=sccnt;
            Maxv[sccnt]=max (w[x],maxv[sccnt]); if (minv[sccnt]==0) Minv[sccnt]=w[x];else minv[sccnt]=min (W[X],MINV[sccnt]);
        if (x==i) break;
    }} void Makesides (int x,int y) {ss++;s[ss].x=x;s[ss].y=y;
    NXTS[SS]=FIRSTS[X];
Firsts[x]=ss;
    } void Makesidek (int x,int y) {kk++;k[kk].x=x;k[kk].y=y;
    NXTK[KK]=FIRSTK[X];
FIRSTK[X]=KK;
int F[lim],ans;
    int findmin (int i) {if (f[i]!=-1) return f[i];
    F[i]=minv[i];
    for (int e=firstk[i];e!=-1;e=nxtk[e]) f[i]=min (F[i],findmin (K[E].Y));
    Ans=max (Ans,maxv[i]-f[i]);
return f[i];
    int main () {memset (firsts,-1,sizeof (firsts));
    memset (nxts,-1,sizeof (nxts));
    memset (firstk,-1,sizeof (FIRSTK));
    memset (nxtk,-1,sizeof (NXTK));
    scanf ("%d%d", &m,&c);
    
    for (a=1;a<=m;a++) scanf ("%d", &w[a]);
        for (a=1;a<=c;a++) {scanf ("%d%d%d", &x,&y,&z);
        Makesides (X,y);
    if (z==2) makesides (y,x);
    for (a=1;a<=m;a++) if (!pre[a]) Tarjan (a); for (a=1;a<=m;a++) for (int e=firsts[a];e!=-1;e=nxts[e]) if (scc[a]!=scc[s[E].Y]) Makesidek (Scc[s[e].y],scc[a]);
    memset (F,-1,sizeof (f));
    Findmin (Scc[m]);
    cout<<ans<<endl;
return 0;
 }




And then the SPFA practice

(Borrow SPFA's thoughts to update to the maximum of each point)

SPFA can find the maximum minimum value of each point over and over again.

But there's something wrong with that, because the last thing to do is go to N.

You can go from 1 to I, but you may not go from I to n.

But because the data is weak (-.-) actually can ac ...


There's another one, two times SPFA.

The first time to go from 1 to find the minimum value

The second time to go from N to find the maximum value

This is supposed to be a problem.

And then I tried to write it.

It feels good to write.

#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <cstdlib
> #include <algorithm> #include <queue> using namespace std;
const int lim=100011;
const int inf=999999999; struct Self{int x,y;}
S[LIM*10],K[LIM*10];
int firsts[lim*10],nxts[lim*10];
int firstk[lim*10],nxtk[lim*10];
int ss,kk;
int W[lim];
int Maxv[lim],minv[lim];

int M,n,a,b,c,x,y,z,ans;
    void makesides (int x,int y) {ss++;s[ss].x=x;s[ss].y=y;
    NXTS[SS]=FIRSTS[X];
Firsts[x]=ss;
    } void Makesidek (int x,int y) {kk++;k[kk].x=x;k[kk].y=y;
    NXTK[KK]=FIRSTK[X];
FIRSTK[X]=KK;
} queue<int>q;
BOOL Inq[lim];
    void Spfamin () {int A;
    memset (inq,0,sizeof (INQ));
    Q.push (1); inq[1]=1;
    for (a=1;a<=m;a++) Minv[a]=inf;
    MINV[1]=W[1];
        while (!q.empty ()) {int U=q.front (); Q.pop (); for (int e=firsts[u];e!=-1;e=nxts[e]) if (Minv[s[e].y]>minv[u]) {minv[s[e].y]=min (minv[u],w[
 S[E].Y]);           if (!inq[s[e].y]) {inq[s[e].y]=1;
            Q.push (S[E].Y);
    }} void Spfamax () {int A;
    memset (inq,0,sizeof (INQ));
    Q.push (m); inq[m]=1;
    for (a=1;a<=m;a++) Maxv[a]=-inf;
    MAXV[M]=W[M];
        while (!q.empty ()) {int U=q.front (); Q.pop (); for (int e=firstk[u];e!=-1;e=nxtk[e]) if (Maxv[k[e].y]<maxv[u]) {Maxv[k[e].y]=max (maxv[u],w[
            K[E].Y]);
                if (!inq[k[e].y]) {inq[k[e].y]=1;
            Q.push (K[E].Y);
    int main () {memset (firsts,-1,sizeof (firsts));
    memset (nxts,-1,sizeof (nxts));
    memset (firstk,-1,sizeof (FIRSTK));
    memset (nxtk,-1,sizeof (NXTK));
    scanf ("%d%d", &m,&c);

    for (a=1;a<=m;a++) scanf ("%d", &w[a]);
        for (a=1;a<=c;a++) {scanf ("%d%d%d", &x,&y,&z);
        Makesides (X,y);
        Makesidek (Y,X);
  if (z==2)      {makesides (y,x);
        Makesidek (X,y);
    } spfamin ();
    
    Spfamax ();
    for (a=1;a<=m;a++) Ans=max (Ans,maxv[a]-minv[a]);
    cout<<ans<<endl;
return 0;
 }



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.