zoukankan      html  css  js  c++  java
  • JDOJ 1070: phoneline

    JDOJ 1070: phoneline

    JDOJ传送门

    Description

    小h最近准备给家里新装条电话线,好让他在奥运假期能够天天上网冲浪,不用再忍受那昂贵的无线上网。 电信局的工作人员对小h说,电话线网络上有n个站点,它们用m条边来连接,小h家的站点在1号,连接的终点在n号,站点之间有电线连接,而且有一定的费用,然后因为暑期的原因,在1号站点连接到n号站点的线路上有k条线是免费的,然后在这条线路剩下的线中费用最大的为小h连接到n号站要付的费用。 当然,小h希望他要付的钱最少,于是他就出了这道题,希望有人能帮帮他。

    Input

    第一行: n,m,k,意义如上文所述。(1<n<=1000,1<m<=n*(n-1)/2)
    以下m行,每行3个正整数s,t,cost,指从s站到t站的费用是cost.(即t到s的费用也是cost)
    1<s,t<=n,0<=cost<=10000
    注意:可能会出现重边或自环

    Output

    一个正整数,表示最小的费用。

    Sample Input

    5 6 1 2 1 3629 3 2 8034 4 3 7348 5 4 3689 4 4 7266 5 5 6088

    Sample Output

    7348


    题解:

    和运输计划这道题的思路有些同源(其实差距还是蛮大的)

    一看到最长路最短想二分答案。

    判断当前答案是否合法的思路:把全图所有比当前答案大的边全部打上标记,统计从1到n最少能经过多少条带标记的边,如果大于k,就不合法,小于k,就合法了。

    如何统计“最少经过多少条带标记的边呢”?很简单,新建一个边权数组跑最短路即可。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define R register
    using namespace std;
    const int maxn=1010;
    const int maxm=5*1e5;
    int n,m,k,maxx;
    bool v[maxn];
    int dist[maxn];
    int tot,to[maxm<<1],nxt[maxm<<1],val[maxm<<1],head[maxn],val1[maxm<<1];
    char *p1,*p2,buf[100000];
    #define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
    inline int read()
    {
        int x=0,f=1;
        char ch=nc();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=nc();
        }
        while(ch>='0'&&ch<='9')
            x=x*10+ch-'0',ch=nc();
       	return x*f;
    }
    inline void add(int x,int y,int z)
    {
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	val[tot]=z;
    	head[x]=tot;
    }
    inline void dijkstra(int start)//源点
    {
        int temp,k,y;
        memset(dist,0x3f,sizeof(dist));
        memset(v,0,sizeof(v));
        dist[start]=0;
        for(R int i=1;i<=n;i++)
        {
            temp=1<<30;
            for(R int j=1;j<=n;j++)
                if(dist[j]<temp && v[j]==0)
                    k=j,temp=dist[j];
            v[k]=1;
            for(R int j=head[k];j;j=nxt[j])
            {
                y=to[j];
                if(dist[y]>dist[k]+val1[j])
                    dist[y]=dist[k]+val1[j];
            }
    	}
    }
    inline void dfs(int d)
    {
    	for(R int i=1;i<=n;i++)
    		for(R int j=head[i];j;j=nxt[j])
    			if(val[j]>d)
    				val1[j]=1;
    }
    inline bool check(int x)
    {
    	memset(val1,0,sizeof(val1));
    	dfs(x);
    	dijkstra(1);
    	return dist[n]>k?0:1;
    }
    int main()
    {
    	n=read();m=read();k=read();
    	for(R int i=1;i<=m;i++)
    	{
    		int x,y,z;
    		x=read();y=read();z=read();
    		add(x,y,z);
    		add(y,x,z);
    		maxx=max(maxx,z);
    	}
    	int l=0,r=maxx;
    	while(l<r)
    	{
    		int mid=(l+r)>>1;
    		if(check(mid))
    			r=mid;
    		else
    			l=mid+1;
    	}
    	printf("%d",l);
    	return 0;
    }
    
  • 相关阅读:
    数学基础
    Codeforces Beta Round 84 (Div. 2 Only)
    Codeforces Round 256 (Div. 2)
    Codeforces Round FF(Div. 2)
    Codeforces Round 254 (Div. 2)
    Python3 集合(无序的set)
    Python3 字典(map)
    Python3 元组
    Python3 列表
    初等数论及其应用——唯一分解定理
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13752908.html
Copyright © 2011-2022 走看看