Contest20140705 testA 二分

testA


输入文件: testA.in 输出文件testA.out 时限2000ms


问题描述:


有一个城市拥有N个节点,被M条有权无向路径连接。现在你要在一个地方(可以在路径上当然也可以在节点上)开设一家咖啡馆,使得所有节点达到这个咖啡馆的最短路里面最大值最小(也就是说离咖啡馆最远的节点距离尽可能得小),求出这个最大值的最小值。



输入描述:

第一行NM

2M+1行,每行三个整数U,V,W。表示从UV有一条权值为W的无向边。


输出描述:

一行一个数表示答案。四舍五入至2位小数


数据范围N<=200 , W<=100000 , M<=19900


样例输入:

3 2
1 2 100
2 3 1


样例输出:

50.50

这道题考场上我是直接输出了最小生成树的重心。是当时我误认为在这道题里面,最小生成树可以等效为最短路树。

正解是二分答案,判断是否有任何一条边可以安咖啡馆。

至少A了后觉得这道题的确很简单。

还有以后要注意关于交题前要删注释,小数位数按题目所说的写。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXV 170000
#define MAXE 170000
#define MAXN 900 
#define PROB "testA"
#define INF 0x3f3f3f3f
struct Edge
{
        int np,val;
        Edge *next;
        bool flag;
}E[MAXE],*V[MAXV];
int m,n;
int map[MAXN][MAXN];
struct aaa
{
        int x,y,d;
}el[MAXE];
int tope=-1,topl=-1;
void addedge(int x,int y,int z)
{
        el[++topl].x=x;
        el[topl].y=y;
        el[topl].d=z;
        E[++tope].np=y;
        E[tope].val=z;
        E[tope].next=V[x];
        V[x]=&E[tope];
        E[++tope].np=x;
        E[tope].val=z;
        E[tope].next=V[y];
        V[x]=&E[tope];
}
void init()
{
        int i,j,k;
        for (i=1;i<=n;i++)
        {
                for (j=1;j<=n;j++)
                {
                        for (k=1;k<=n;k++)
                        {
                                if (map[j][k]>map[j][i]+map[i][k])
                                        map[j][k]=map[j][i]+map[i][k];
                        }
                }
        }
}
pair<int,int> seg[MAXN];
int tops=-1,rg;
void set_range(int x)
{
        tops=-1;
        rg=x;
}
void add_seg(int x,int y)
{
        tops++;
        if (x>y)throw "E";
        seg[tops].first=x;
        seg[tops].second=y;
}
bool full()
{
        int i,x=0;
        sort(seg,&seg[tops+1]);
        for (i=0;i<=tops;i++)
        {
                if (x<seg[i].first)return false;
                if (x>seg[i].second)continue;
                x=seg[i].second+1;
        }
        if (x>rg)return true;
        return false;
}
int main()
{

        freopen(PROB".in","r",stdin);    
//        freopen(PROB".out","w",stdout);
        int i,j,k,x,y,z;
        scanf("%d%d",&n,&m);
        memset(map,INF,sizeof(map));
        for (i=0;i<m;i++)
        {
                scanf("%d%d%d",&x,&y,&z);
                addedge(y,x,z*2);
                map[x][y]=map[y][x]=min(map[x][y],z*2);
        }
        for (i=1;i<=n;i++)map[i][i]=0;
        init();
        int l,r,mid;
        l=0;r=10000006;
        int flag=-1;
        while (l+1<r)
        {
                mid=(l+r)/2;
                flag=0;
                for (i=0;i<=topl;i++)
                {
                        set_range(el[i].d);
                        for (j=1;j<=n;j++)
                        {
                                x=mid-map[el[i].x][j];
                                y=mid-map[el[i].y][j];
                                if (x<0&&y<0)
                                {
                                        add_seg(0,el[i].d);
                                        break;
                                }
                                if (x>=el[i].d||y>=el[i].d)
                                {
                                        continue;
                                }
                                if (x+y>=el[i].d)
                                {
                                        continue;
                                }
                                add_seg(max(0,x+1),min(el[i].d,el[i].d-y-1));
                                
                        }
                        if (!full())flag=1;
                        if (flag==1)
                                break;
                }
                if (flag==0)
                {
                        l=mid;
                        continue;
                }
                if (flag==1)
                {
                        r=mid;
                        continue;
                }
        }
        double ans=r/2.0;
        printf("%.2lf",ans);
        return 0;
}
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

本博客已停用,新博客地址:http://mhy12345.xyz

原文地址:https://www.cnblogs.com/mhy12345/p/3827025.html