poj 3662 Telephone Lines 图论

17 篇文章 0 订阅
17 篇文章 0 订阅
最短路径的变形
题目意思: 找一条连接1到n的路径,其中k条路径免费,剩下的边最大的就是花费,要求花费最小。

解法:ans[i][j]表示到达i顶点,使用了j条免费边的花费。然后就用spfa的那种思想来搞就行了。



#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=10000+10;
struct node
{
    intto,w,next,from;
}e[maxn<<1];
int head[maxn],lon;
void edgemake(int from,int to,int w)
{
    e[++lon].to=to;
    e[lon].from=from;
    e[lon].w=w;
    e[lon].next=head[from];
    head[from]=lon;
}

int ans[1111][1111],text[1111][1111];
int quef[11111111],quet[11111111];
int spfa(int n,int m)
{
    memset(ans,-1,sizeof(ans));
    int front=1,end=0;
    quef[++end]=1;
    quet[++end]=0;
    text[1][0]=1;
    ans[1][0]=0;
    while(front<=end)
    {
        int u=quef[front],t=quet[front++];
//         printf("%d %d\n",u,t);
        for(int k=head[u];k!=-1;k=e[k].next)
        {
            intv=e[k].to;
            if(t<m)
            {
                if(ans[v][t+1]>ans[u][t]||ans[v][t+1]==-1)
                {
                    ans[v][t+1]=ans[u][t];
                    if(text[v][t+1]==0)
                    {
                        text[v][t+1]=1;
                        quef[++end]=v;
                        quet[end]=t+1;
                    }
                }
            }
            inttmp=max(ans[u][t],e[k].w);
            if(ans[v][t]>tmp||ans[v][t]==-1)
            {
                ans[v][t]=tmp;
                if(text[v][t]==0)
                {
                    text[v][t]=1;
                    quef[++end]=v;
                    quet[end]=t;
                }
            }
        }
        text[u][t]=0;
    }
    int ret=111111111;
    for(inti=0;i<=m;i++)
    ret=min(ans[n][i],ret);
    return(ret);
}

int main()
{
    int n,m,k;
    scanf("%d %d%d",&n,&m,&k);
    lon=0;
    memset(head,-1,sizeof(head));
    for(inti=1;i<=m;i++)
    {
        int from,to,w;
        scanf("%d %d%d",&from,&to,&w);
        edgemake(from,to,w);
        edgemake(to,from,w);
    }
    intanswer=spfa(n,k);
    printf("%d\n",answer);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值