poj 3662 Telephone Lines 图论

来源:互联网 发布:2017中超守门员数据 编辑:程序博客网 时间:2024/06/01 09:22
最短路径的变形
题目意思: 找一条连接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;
}