Try Again

汤圆防漏理论

链接:https://www.nowcoder.com/acm/contest/117/F
来源:牛客网

ghc很喜欢吃汤圆,但是汤圆很容易被粘(zhān)漏。

根据多年吃汤圆经验,ghc总结出了一套汤圆防漏理论:

互相接触的汤圆容易粘(zhān)在一起,并且接触面积不同,粘(zhān)在一起的粘(nián)度也不同。

当ghc要夹起一个汤圆时,这个汤圆和现在碗里与这个汤圆接触的所有汤圆之间的粘(nián)度的和,如果大于汤圆的硬度,这个汤圆就会被粘(zhān)漏。

今天ghc又要煮汤圆啦,今天要煮n个汤圆,并且摆盘的方法已经设计好:

汤圆按照编号,有m对汤圆互相接触,用xi, yi, zi表示编号为xi和yi的两个汤圆互相接触,粘(nián)度为zi

汤圆当然是越软越好吃,但是ghc的厨艺只允许把所有汤圆煮成同样的硬度。那么,汤圆的硬度最小可以是多少,可以满足吃的过程中,存在一种夹汤圆的顺序,使得没有汤圆会被粘(zhān)漏呢?

注意:

不考虑汤圆的重力作用;

不能同时夹多个汤圆;

吃完汤圆一定要喝点汤。

输入描述:

第一行是一个正整数T(≤ 5),表示测试数据的组数,

对于每组测试数据,

第一行是两个整数n,m(1≤ n,m≤ 100000),

接下来m行,每行包含三个整数xi, yi, zi(1≤ xi, yi ≤ n, xi ≠ yi, 1 ≤ zi ≤ 1000000),

同一对汤圆不会出现两次。

输出描述:

对于每组测试数据,输出一行,包含一个整数,表示汤圆硬度的最小值。
示例1

输入

1
4 6
1 2 2
1 3 2
1 4 2
2 3 3
2 4 3
3 4 5

输出

6
二分硬度
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) ((a,0,sizeof(a)))
typedef long long ll;
ll n,m,t,x,y,z;
ll a[100006];
vector<pair<ll,ll> >v[100006];
int solve(ll value)
{
    int vis[100006],rvis[100006];
    ll mid[100006];
    queue<ll>q;
    memset(vis,0,sizeof(vis));
    memset(rvis,0,sizeof(rvis));
    for(int i=1;i<=n;i++)
    {
        mid[i]=a[i];
        if(a[i]<=value)
        {
            q.push(i);
            rvis[i]=1;
        }
    }
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        vis[now]=1;
        for(int i=0;i<v[now].size();i++)
        {
            if(vis[v[now][i].first])continue;
            mid[v[now][i].first]-=v[now][i].second;
            if(mid[v[now][i].first]<=value && !rvis[v[now][i].first])
            {
                q.push(v[now][i].first);
                rvis[v[now][i].first]=1;
            }
        }
    }
    for(int i=1;i<=n;i++)
        if(!vis[i]) return 1;
    return 0;
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        for(int i=0;i<=n;i++)
            v[i].clear();
        memset(a,0,sizeof(a));
        for(int i=0;i<m;i++)
        {
            scanf("%lld%lld%lld",&x,&y,&z);
            v[x].push_back(make_pair(y,z));
            v[y].push_back(make_pair(x,z));
            a[x]+=z;
            a[y]+=z;
        }
        ll l=0,r=1e12;
        while(l<=r)
        {
            ll ans=l+r>>1;
            if(!solve(ans)) r=ans-1;
            else l=ans+1;
        }
        printf("%lld\n",l);
    }
    return 0;
}

 

posted @ 2018-04-30 15:48  十年换你一句好久不见  阅读(396)  评论(0编辑  收藏  举报