[codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)

题目链接:http://codeforces.com/problemset/problem/852/D

题目大意:

有V个点,N个队伍,E条边,经过每条边有个时间,告诉你初始N个队伍的位置,求至少有K个队伍在不同的点的最短时间

题解:

我们二分答案时间,显然具有单调性。先floyd预处理两点之间的最短路,二分答案后把每个人和他可以走到的点连起来,跑一次最大匹配。若最大匹配数大于等于k,说明当前答案小了,否则大了

(每个匹配相等于一个人和他最终去的位置)

#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;

const int N=600+15;
const int inf=1e9+7;
const int Inf=1731311;
int v,e,n,k;
int pos[N],d[N][N],mp[N][N],match[N],vis[N];
inline int read()
{
    char ch=getchar();
    int s=0,f=1;
    while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) f=-1;ch=getchar();}
    while (ch>=‘0‘&&ch<=‘9‘) {s=(s<<3)+(s<<1)+ch-‘0‘;ch=getchar();}
    return s*f;
}
void floyd()
{
    for (int k=1;k<=v;k++)
        for (int i=1;i<=v;i++)
            for (int j=1;j<=v;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
bool dfs(int x)
{
    for (int i=1;i<=v;i++)
    {
        if (vis[i]||!mp[x][i]) continue;
        vis[i]=1;
        if (match[i]==-1||dfs(match[i]))
        {
            match[i]=x;
            return true;
        }
    }
    return false;
}
int check(int l)
{
    memset(match,-1,sizeof(match));
    for (int i=1;i<=n;i++)
        for (int j=1;j<=v;j++)
         mp[i][j]=(d[pos[i]][j]<=l);
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if (dfs(i)) ans++;
    }
    return ans;
}
int main()
{
    v=read();e=read();n=read();k=read();
    for (int i=1;i<=v;i++)
        for (int j=1;j<=v;j++) if (i!=j) d[i][j]=inf;
    for (int i=1;i<=n;i++) pos[i]=read();
    for (int i=1,u,v,w;i<=e;i++)
    {
        u=read();v=read();w=read();
        d[u][v]=d[v][u]=min(d[u][v],w);
    }
    floyd();
    int l=0,r=Inf,ans=Inf;
    while (l<r)
    {
        int mid=l+r>>1;
        if (check(mid)>=k) r=mid,ans=min(ans,r);
        else l=mid+1;
    }
    if (ans==Inf) puts("-1");
    else printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/xxzh/p/9762720.html

时间: 2024-08-01 12:32:36

[codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)的相关文章

Codeforces 448(#256 (Div. 2) ) 解题报告

A: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月17日 星期四 21时44分03秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bits

Codeforces Round #259 (Div. 2) 解题报告

终于重上DIV1了.... A:在正方形中输出一个菱形 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月01日 星期五 23时27分55秒 4 5 #include<vector> 6 #include<set> 7 #include<deque> 8 #include<stack> 9 #include<bitset> 10 #inclu

Codeforces 459(#261 (Div. 2) ) 解题报告

A:给你一个正方形的两点,让你求其余亮点 解法:乱搞 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月15日 星期五 23时24分04秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<

Codeforces 450(#257 (Div. 2) ) 解题报告

A: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月19日 星期六 21时01分28秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bits

Codeforces Round #262 (Div. 2)解题报告

详见:http://robotcator.logdown.com/posts/221514-codeforces-round-262-div-2 1:A. Vasya and Socks   http://codeforces.com/contest/460/problem/A 有n双袜子,每天穿一双然后扔掉,每隔m天买一双新袜子,问最多少天后没有袜子穿.. 简单思维题:以前不注重这方面的训练,结果做了比较久,这种题自己边模拟边想.不过要多考虑trick ```c++ int main(){ i

Codeforces Round #616 (Div. 2)解题报告

Codeforces Round #616 (Div. 2)解题报告 A. Even But Not Even 找两个奇数就行了. #include<bits/stdc++.h> using namespace std; void solve() { int n; string s; cin >> n >> s; string ans = ""; for(int i = 0; i < n; i++) { if(int(s[i] - '0')%2

Codeforces 486(#277 Div 2) 解题报告

A:比较简单 判断奇偶  一个公式即可 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年11月11日 星期二 22时43分28秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11

codeforces 557B. Pasha and Tea 解题报告

题目链接:http://codeforces.com/problemset/problem/557/B 题目意思:有 2n 个茶杯,规定第 i 个茶杯最多只能装 ai 毫升的水.现在给出 w 毫升的水,需要把这w毫升(可以不用光)的水倒入到这 2n 个茶杯中,使得分给n个男的每个水杯的水恰好是n个女的2倍(注意,n个男的水杯装的水是一样的,n 个女也是).现在问的是,怎样使得2n个杯装的水最多,求出这个值. ********************************************

codeforces 507B. Amr and Pins 解题报告

题目链接:http://codeforces.com/problemset/problem/507/B 题目意思:给出圆的半径,以及圆心坐标和最终圆心要到达的坐标位置.问最少步数是多少.移动见下图.(通过圆上的边固定转动点,然后转动任意位置,圆心就会移动了,这个还是直接看图吧) 解题的思路就是,两点之间,距离最短啦----要想得到最少步数,我们需要保证圆心在这条连线上移动,每次转动的角度是180度,而每步移动的距离是2r,直到两个圆交叉,要注意最后一步转动的角度可能会小于180度.最后就是注意精