[kuangbin带你飞]专题四 最短路练习

A. POJ 2387  Til the Cows Come Home

模板题.

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

const int INF =1000000000;
int mincost[1010];
int cost[1010][1010];
bool used[1010];

int main()
{
    int T,N;
    while(cin>>T>>N)
    {
        int from,to,w;
        memset(cost,0x3f,sizeof(cost));
        for(int i=0;i<T;i++)
        {
            cin>>from>>to>>w;
            cost[from][to]=cost[to][from]=min(cost[from][to],w);
        }

        memset(mincost,0x3f,sizeof(mincost));
        memset(used,0,sizeof(used));

        mincost[1]=0;
        while(1)
        {
            int v=-1;
            for(int u=1;u<=N;u++)
                if(!used[u]&&(v==-1||mincost[u]<mincost[v]))
                    v=u;
            if(v==-1)
                break;
            used[v]=true;
            for(int u=1;u<=N;u++)
                mincost[u]=min(mincost[u],mincost[v]+cost[u][v]);
        }
        printf("%d\n",mincost[N]);
    }
    return 0;
}
View Code

B. POJ 2253  Frogger

模板题.把任意两块石头之间的距离算出来作为最短路.然后套模板.

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;
struct Point{
    int x,y;
}point[250];

double dist[250][250];
double lowedge[250];
bool used[250];

double fun(int i,int j)
{
    return sqrt((double)(point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y));
}

int n;
int main()
{
    int icase=0;
    while(cin>>n&&n)
    {
        memset(dist,0,sizeof(dist));
        for(int i=0;i<n;i++)
        {
            cin>>point[i].x>>point[i].y;
            for(int j=0;j<i;j++)
                dist[i][j]=dist[j][i]=fun(i,j);
        }

        for(int i=0;i<n;i++)
            lowedge[i]=dist[0][i];
        memset(used,0,sizeof(used));
        lowedge[0]=0;

        while(1)
        {
            int v=-1;
            for(int u=0;u<n;u++)
                if(!used[u]&&(v==-1||lowedge[u]<lowedge[v]))
                    v=u;
            if(v==-1)
                break;
            used[v]=true;
            for(int u=0;u<n;u++)
                if(!used[u]&&max(lowedge[v],dist[v][u])<lowedge[u])
                    lowedge[u]=max(lowedge[v],dist[u][v]);
        }
        printf("Scenario #%d\n",++icase);
        printf("Frog Distance = %.3f\n\n",lowedge[1]);
    }
    return 0;
}
View Code

C. POJ 1797  Heavy Transportation

题意:求出起点到终点的每条路径的最小权值中最大的那个权值。

思路:选择dist[u]和cost[u][v]中较小的那个来收缩dist[v].

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

int dist[1100][1100];
int mincost[1100];
bool used[1100];
int n,m;

int main()
{
    int T,icase=0;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        int x,y,w;
        memset(dist,0,sizeof(dist));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            dist[x][y]=dist[y][x]=w;
        }

        memset(used,0,sizeof(used));
        for(int i=1;i<=n;i++)
            mincost[i]=dist[1][i];

        while(1)
        {
            int v=-1;
            for(int u=1;u<=n;u++)
                if(!used[u]&&(v==-1||mincost[u]>mincost[v]))
                    v=u;
            if(v==-1)
                break;
            used[v]=true;
            for(int u=1;u<=n;u++)
                if(!used[u]&&min(mincost[v],dist[v][u])>mincost[u])
                    mincost[u]=min(mincost[v],dist[v][u]);
        }
        printf("Scenario #%d:\n",++icase);
        printf("%d\n\n",mincost[n]);
    }
    return 0;
}
View Code

D. POJ 3286  Silver Cow Party

题意:有N个农场,每个农场有一头牛。农场X举行party,其他农场的牛前去参加,然后在回家。求所有牛来回距离之和的

   最小值。

思路:先用dijkstra求目标点到个点的最短路。然后再建立一个反图,即将每一条反向。再求一次         目标点到每个点的最短路,

         两个最短路的各点距离之和即为所求。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

int dist[1100][1100];
int mincost[2][1100];
bool used[2][1100];
int n,m,t;

int main()
{
    while(cin>>n>>m>>t)
    {
        int x,y,w;
        memset(dist,0x3f,sizeof(dist));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            dist[x][y]=w;
        }

        memset(used,0,sizeof(used));
        memset(mincost,0x3f,sizeof(mincost));
        mincost[0][t]=mincost[1][t]=0;

        while(1)
        {
            int v=-1;
            for(int u=1;u<=n;u++)
                if(!used[0][u]&&(v==-1||mincost[0][u]<mincost[0][v]))
                    v=u;
            if(v==-1)
                break;
            used[0][v]=true;
            for(int u=1;u<=n;u++)
                if(!used[0][u]&&mincost[0][u]>mincost[0][v]+dist[v][u])
                    mincost[0][u]=mincost[0][v]+dist[v][u];
        }

        while(1)
        {
            int v=-1;
            for(int u=1;u<=n;u++)
                if(!used[1][u]&&(v==-1||mincost[1][u]<mincost[1][v]))
                    v=u;
            if(v==-1)
                break;
            used[1][v]=true;
            for(int u=1;u<=n;u++)
                if(!used[1][u]&&mincost[1][u]>mincost[1][v]+dist[u][v])
                    mincost[1][u]=mincost[1][v]+dist[u][v];
        }
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,mincost[0][i]+mincost[1][i]);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

E. POJ 1860  Currency Exchange

题意:存在N种货币,M种交换规则。每个交换规则在两种货币之间交换,交换有手续费和汇率。

     交换所得=(交换金额-手续费)*汇率。问你是否存在一种交换使得你的金钱变多。

思路:通过bell_man算法 循环n-1次。然后再枚举每一条边,看还能否松弛,如果可以就说明存

        在这样的交换。否则不存在。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

struct edge{
    int from,to;
    double r,c;
}ed[220];

int dist[1100][1100];
double mincost[110];
bool used[110];
int n,m,s;
double v;

int main()
{
    int from,to;
    double r1,c1,r2,c2;
    while(cin>>n>>m>>s>>v)
    {
        int flag=0;
        memset(ed,0,sizeof(ed));
        memset(mincost,0,sizeof(mincost));
        for(int i=0;i<m;i++)
        {
            cin>>from>>to>>r1>>c1>>r2>>c2;
            ed[2*i].from=from;
            ed[2*i].to=to;
            ed[2*i].r=r1;
            ed[2*i].c=c1;
            ed[2*i+1].from=to;
            ed[2*i+1].to=from;
            ed[2*i+1].r=r2;
            ed[2*i+1].c=c2;
        }

        mincost[s]=v;
        for(int i=1;i<n;i++)
        {
            int update=0;
            for(int j=0;j<2*m;j++)
                if(mincost[ed[j].to]<(mincost[ed[j].from]-ed[j].c)*ed[j].r)
                    update=1,mincost[ed[j].to]=(mincost[ed[j].from]-ed[j].c)*ed[j].r;
            if(!update)
                break;
        }
        for(int j=0;j<2*m;j++)
            if(mincost[ed[j].to]<(mincost[ed[j].from]-ed[j].c)*ed[j].r)
            {
                flag=1;
                break;
            }
        printf("%s\n",flag?"YES":"NO");
    }
    return 0;
}
View Code

F. POJ 3259  Wormholes

题意:有N个农场,M条边,W个虫洞。虫洞相当于一条权值为负的边。问你是否存在一条路径使得你回到出发时间之前。

思路:同上题基本一样。只是松弛的方式不同。这道题同样是通过bell_man算法 循环n-1次。然后再枚举每一条边,看是否还能松弛,如果可以,就存在这样的路径,否则不存在。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

struct edge{
    int from,to,w;
}ed[5500];
double mincost[550];
int n,m,w,t;

int main()
{
    cin>>t;
    while(t--)
    {
        memset(ed,0,sizeof(ed));
        memset(ed,0x3f,sizeof(mincost));
        int from,to,cost,flag=0;
        cin>>n>>m>>w;
        for(int i=0;i<m;i++)
        {
            cin>>from>>to>>cost;
            ed[2*i].from=ed[2*i+1].to=from;
            ed[2*i].to=ed[2*i+1].from=to;
            ed[2*i].w=ed[2*i+1].w=cost;
        }
        for(int i=0;i<w;i++)
        {
            cin>>from>>to>>cost;
            ed[i+2*m].from=from;
            ed[i+2*m].to=to;
            ed[i+2*m].w=cost*(-1);
        }
        for(int i=1;i<n;i++)
        {
            int update=0;
            for(int j=0;j<2*m+w;j++)
                if(mincost[ed[j].to]>mincost[ed[j].from]+ed[j].w)
                    update=1,mincost[ed[j].to]=mincost[ed[j].from]+ed[j].w;
            if(!update)
                break;
        }
        for(int j=0;j<2*m+w;j++)
                if(mincost[ed[j].to]>mincost[ed[j].from]+ed[j].w)
                {
                    flag=1;
                    break;
                }
        printf("%s\n",flag?"YES":"NO");
    }
    return 0;
}
View Code

G POJ 1502  MPI Maelstrom

题意:给你n个节点,给你一个下三角矩阵,描述两点之间传送消息的cost,‘X’表示这两点之间不能直接发送消息。询问第一个节点到其他所有节点发送消息的花费的最小值。

思路:直接dijkstra就好,难点在于输入矩阵的处理。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

int n;
int dist[110][110];
int mincost[110];
bool used[110];

int strtoint(char* str)
{
    if (str[0] == 'x') return -1;
    int ret = 0;
    while (*str)
    {
        ret = ret * 10 + *str++ - '0';
    }
    return ret;
}

int main()
{
    char str[35];
    int dis;
    scanf("%d",&n);
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            scanf("%s", str);
            dis = strtoint(str);
            dist[i][j] = dist[j][i] = dis;
        }
    }
    memset(mincost,0x3f,sizeof(mincost));
    mincost[0]=0;
    while(1)
    {
        int v=-1;
        for(int u=0;u<n;u++)
            if(!used[u]&&(v==-1||mincost[v]>mincost[u]))
                v=u;
        if(v==-1)
            break;
        used[v]=true;
        for(int u=0;u<n;u++)
            if(dist[u][v]>=0)
                mincost[u]=min(mincost[u],mincost[v]+dist[u][v]);
    }
    int ans=0;
    for(int i=0;i<n;i++)
        ans=max(ans,mincost[i]);
    printf("%d\n",ans);
    return 0;
}
View Code

H POJ 3660 Cow Contest

题意:有n头牛,每一头牛都有一定的编程能力值。需要将这些牛根据他们的编程能力值排序。已知任意两头牛之间可以比赛,编程能力值高的获胜。现在告诉你m个胜负关系。

        询问能确定位置的牛有多少头。

思路:这个题挺有意思。先通过floyd算法得到任意两头牛之间的rank高低。然后根据传递闭包,求出每一头牛的度数(出度+入度),然后判断,如果一个点的度数等于n-1,

        则这个点的位置就是确定的。最后统计,输出答案。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

int ma[110][110];
int de[110];

int main()
{
    int n,m,from,to,ans=0;
    cin>>n>>m;
    memset(de,0,sizeof(de));
    memset(ma,0,sizeof(ma));
    for(int i=0;i<m;i++)
    {
        cin>>from>>to;
        ma[from][to]=1;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                if(ma[j][i]&&ma[i][k])
                    ma[j][k]=1;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(ma[i][j])
            {
                de[i]++;
                de[j]++;
            }
    for(int i=1;i<=n;i++)
        if(de[i]==n-1)
            ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

I POJ 2240 Arbitrage

题意:告诉你n种货比两两之间的汇率,询问是否可能通过交换使钱变多。

思路:floyd算法,然后看是否存在dist[i][i]>1,即通过交换使得钱变多。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;
map<string,int> m;
double dist[50][50];
int main()
{
    int n,d,icase=0;
    string str1,str2;
    double w;
    while(cin>>n&&n)
    {
        int flag=0;
        memset(dist,0,sizeof(dist));
        for(int i=0;i<n;i++)
        {
            cin>>str1;
            m[str1]=i;
            dist[i][i]=1;
        }
        cin>>d;
        for(int i=0;i<d;i++)
        {
            cin>>str1>>w>>str2;
            dist[m[str1]][m[str2]]=w;
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                    dist[j][k]=max(dist[j][k],dist[j][i]*dist[i][k]);

        for(int i=0;i<n;i++)
            if(dist[i][i]>1)
            {
                flag=1;
                break;
            }
        printf("Case %d: %s\n",++icase,flag?"Yes":"No");
    }
    return 0;
}
View Code

J POJ 1511 Invitation Cards

题意:早上从某一点出发去所有其他点发传单,然后晚上在回来。求总的最小花费。

思路:思路跟D题几乎一样,但是数据很大,需要用SPFA来做。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",x)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)(v).size()

#define maxn 1000100
#define INF (1LL<<60)
using namespace std;

int C,M,S,T,P,Q;
bool vis[maxn];
ll dist[maxn];
int c[maxn];
struct Edge
{
    int v;
    ll w;
    Edge *next;
};Edge e1[maxn],e2[maxn];

bool relax(int u,int v,ll w)
{
    if(dist[u]+w<dist[v]){
        dist[v]=dist[u]+w;
        return true;
    }
    return false;
}

void add_edge(int u,int v,ll w,Edge *e)
{
    Edge *pre=&e[u];
    Edge *p=(Edge*)malloc(sizeof(Edge));
    p->v=v;p->w=w;
    p->next=pre->next;
    pre->next=p;
}

bool spfa(Edge *e)
{
    for(int i=1;i<=P;i++) dist[i]=(i==S)?0:INF;
    memset(vis,0,sizeof(vis));
    memset(c,0,sizeof(c));
    queue<int> q;
    q.push(S);
    vis[S]=1;c[S]++;
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(Edge *p=e[u].next;p!=NULL;p=p->next){ 
            int v=p->v;
            ll w=p->w;
            if(relax(u,v,w)){
                if(!vis[v]){
                    q.push(v);
                    vis[v]=1;
                    c[v]++;
                    if(c[v]>P) return false;
                }
            }
        }
    }
    return true;
}


int main()
{
  //  freopen("in.txt","r",stdin);

    scanf("%d",&C);
    while(C--)
    {
        int u,v;
        ll w,ans=0;
        S=1;
        MS0(e1);
        MS0(e2);
        scanf("%d%d",&P,&Q);
        for(int i=0;i<Q;i++)
        {
            scanf("%d%d%lld",&u,&v,&w);
            add_edge(u,v,w,e1);
            add_edge(v,u,w,e2);
        }

        spfa(e1);
        for(int i=2;i<=P;i++)
            ans+=dist[i];
        spfa(e2);
        for(int i=2;i<=P;i++)
            ans+=dist[i];
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

K POJ 3159  Candies

题意:题目告诉你n个人,有m个关系  b的糖果不能比a的糖果多c个,问最后一个人最多拥有多少个糖果。

思路:SPFA最短路,松弛条件换成dist[v]=min(dist[v],dist[u]+w);

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",x)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)(v).size()

#define maxn 1000100
#define INF (1LL<<60)

using namespace std;

struct Edge
{
    int v;
    ll w;
    Edge *next;
}e[35000];
bool vis[35000];
ll dist[35000];

bool relax(int u,int v,ll w)
{
    if(dist[u]+w<dist[v])
    {
        dist[v]=dist[u]+w;
        return true;
    }
    return false;
}

void add_edge(int u,int v,ll w)
{
    Edge *pre=&e[u];
    Edge *p=(Edge *)malloc(sizeof(Edge));
    p->v=v;p->w=w;
    p->next=pre->next;
    pre->next=p;
}

void spfa()
{
    for(int i=0;i<35000;i++) dist[i]=INF;
    MS0(vis);
    dist[1]=0;
    stack<int> s;
    s.push(1);vis[1]=1;
    while(!s.empty())
    {
        int d=s.top();s.pop();vis[d]=0;
        for(Edge *p=e[d].next;p!=NULL;p=p->next)
        {
            if(relax(d,p->v,p->w)&&!vis[p->v])
            {
                s.push(p->v);
                vis[p->v]=1;
            }
        }
    }
}
int main()
{
    int u,v,N,M;
    ll w;
    MS0(e);
    scanf("%d%d",&N,&M);
    for(int i=0;i<M;i++)
    {
        scanf("%d%d%lld",&u,&v,&w);
        add_edge(u,v,w);
    }
    spfa();
    printf("%d\n",dist[N]);
    return 0;
}
View Code

 

----------------------------------好吧,因为未知原因,这个题一直WA,所以并没有AC,所以就没有AC代码了,羞耻的分割线----------------------------------

L POJ 2502  Subway

题意:在笛卡尔坐标系下给出家和学校的坐标,再给你几条地铁线,以及地铁线上的节点,你可以在任意节点上下地铁。地铁的速度是跑步速度的4倍,问你到学校最短的时间。

思路:建图的时候把地铁线上的距离缩短为1/4,然后求出最短路,再除以跑步速度,最后得到答案。

----------------------------------好吧,因为未知原因,这个题一直WA,所以并没有AC,所以就没有AC代码了,羞耻的分割线----------------------------------

 

M POJ 1062  昂贵的聘礼

题意:中文题意,就不解释了。

思路:把每一个物品作为一个节点,每有一种交换就连一条权值为优惠价格的边。然后枚举交换的起始阶级k,然后他可以在k到k+M的阶级之内交换。对于每次枚举,求出

        由起点到任意节点的最短路大小再加上这种物品的价格,取最小值。输出所有枚举的最小值中最小的那个。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long

#define maxn 1000100
#define INF (1<<29)

using namespace std;

int M,N,X,T,V;
int cost[120][120];
int L[120];
int P[120];
int maxl,ans    ;
bool vis[120];
int dist[120];
int main()
{
    //freopen("in.txt","r",stdin);
    for(int i=0;i<120;i++)
        for(int j=0;j<120;j++)
            cost[i][j]=INF;
    cin>>M>>N;
    for(int i=1;i<=N;i++)
    {
        cin>>P[i]>>L[i]>>X;
        maxl=max(maxl,L[i]);
        for(int j=0;j<X;j++)
        {
            cin>>T>>V;
            cost[i][T]=V;
        }
    }
    ans=P[1];
    for(int k=(L[1]<=M?1:L[1]-M);k<=L[1];k++)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=N;i++)    dist[i]=INF;

        dist[1]=0;

        while(1)
        {
            int v=-1;
            for(int u=1;u<=N;u++)
                if(!vis[u]&&(v==-1||dist[u]<dist[v])) v=u;
            if(v==-1)
                break;
            vis[v]=1;
            if(k<=L[v]&&L[v]<=min(k+M,maxl))
                for(int u=1;u<=N;u++)
                    if(k<=L[u]&&L[u]<=min(k+M,maxl))
                    dist[u]=min(dist[u],cost[v][u]+dist[v]);
        }

        for(int i=1;i<=N;i++)
            ans=min(ans,dist[i]+P[i]);

    }
    printf("%d\n",ans);

}
View Code

 

Q HDU 3416  Marriage Match IV

题意:n个城市,m条边,询问互不相交的最短路有多少条。

思路:dijkstra+网络流,可以参考我网络流的题解。

 

posted on 2015-08-20 00:31  onlyAzha  阅读(232)  评论(0编辑  收藏  举报

导航