首页 > 其他分享 >OI_problem 玛丽卡_洛谷P1186

OI_problem 玛丽卡_洛谷P1186

时间:2023-11-25 16:55:17浏览次数:33  
标签:tmp ch 洛谷 边双 路径 mid 生成 P1186 problem

  • 题意

    一个 \(N\) 个点 \(M\) 条边的带边权无向图,要求输出最小的 \(V\) 使得不管去掉哪一条边,都存在从 \(1\) 到 \(n\) 的路径使得边权和不超过 \(V\) 。

  • 思路

    感觉朴素不太好做,考虑二分。

    对于一个二分值,即要判断在关于这个值的生成图中, \(1\) 和 \(n\) 在不在一个边双里。考虑怎么判断一条边要不要加入生成图。现在的主要问题是如何生成这个图。

    给出结论:我们的生成图应该有且仅有所有长度不大于二分值的路径所含的边。等价性如下:

    1. 如果生成图符合边双条件,则断开一条边之后肯定存在一条路径。而如果不存在合法路径,那么可以推出所有路径都通过这条边,矛盾。故可以推出原图符合边双条件。
    2. 如果原图符合边双条件,则这个边双一定也在生成图中。

    而要维护生成图,我们只需要对起点和终点各跑一次最短路就好了。

    复杂度 \(O(N^2+M\log{NV})\)

实现:

#include<bits/stdc++.h>
using namespace std;

template<typename T>
void read( T &r )
{
    r=0; bool w = false; char ch=getchar();
    while( ch <'0' || ch>'9' ) w=!(ch^45),ch=getchar();
    while( ch >='0' && ch <='9' ) r = (r<<1) + (r<<3) + (ch^48), ch=getchar();
    r=w?-r:r;
}

#define MAXN 1000
int n,m;
int w[MAXN+5][MAXN+5];

int dist[2][MAXN+5];
bool vis[MAXN+5];
void dijkstra( int s , int t )
{
    memset(dist[t],0x3f,sizeof(dist[t]));
    memset(vis,0,sizeof(vis));
    dist[t][s] = 0;
    vis[s] = true;
    for(int i=1;i<=n;i++) if( !vis[i] )
        dist[t][i] = min(dist[t][i], dist[t][s] + w[s][i]);
    while( true )
    {
        int tmp = 0;
        for(int i=2;i<=n;i++) if( !vis[i] )
        {
            if( dist[t][tmp] > dist[t][i] )
                tmp = i;
        }
        if( !tmp ) break;
        vis[tmp] = true;
        for(int j=1;j<=n;j++) if( !vis[j] )
            dist[t][j] = min(dist[t][j], dist[t][tmp] + w[tmp][j]);
    }
}

struct node
{
    int to,nxt;
}edg[MAXN*MAXN+5];
int head[MAXN+5],edg_num;
void add( int u , int v )
{
    ++edg_num;
    edg[edg_num].to = v;
    edg[edg_num].nxt = head[u];
    head[u] = edg_num;
}
int dfn[MAXN+5],low[MAXN+5],col[MAXN+5],cnum;
int st[MAXN+5];
void tarjan( int u , int fa )
{
    dfn[u] = low[u] = ++dfn[0];
    st[++st[0]] = u;
    for(int i=head[u],v;i;i=edg[i].nxt) if( (v=edg[i].to) != fa )
    {
        if( !dfn[v] )
        {
            tarjan(v,u);
            low[u] = min(low[v],low[u]);
        }
        low[u] = min(low[u],dfn[v]);
    }
    if( dfn[u] == low[u] )
    {
    	++cnum;
    	int tmp;
    	do
		{
			tmp = st[st[0]--];
			col[tmp] = cnum;
		}
    	while( tmp != u );
	}
}
bool check( int V )
{
    memset(head,0,sizeof(head));edg_num=0;
    st[0]=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            if( min(1ll*dist[0][i] + w[i][j] + dist[1][j],1ll*dist[1][i]+w[i][j]+dist[0][j]) <= 1ll*V )
                add(i,j),add(j,i);
        }
    tarjan(1,0);
    return col[1] == col[n];
}

int main()
{
    memset(w,0x3f,sizeof(w));

    read(n),read(m);
    for(int i=1;i<=m;i++)
    {
        int u,v;
        read(u),read(v);
        read(w[u][v]), w[v][u] = w[u][v];
    }
    dijkstra(1,0); 
    dijkstra(n,1);
    int l=1, r=(n-1)*1000, ans=r+1;
    while( l <= r )
    {
        int mid=l+r>>1;
        if( check(mid) )
            ans = mid, r = mid-1;
        else l = mid+1;
    }
    printf("%d",ans);
    return 0;
}

标签:tmp,ch,洛谷,边双,路径,mid,生成,P1186,problem
From: https://www.cnblogs.com/imb514/p/17855708.html

相关文章

  • [Codeforces] CF1703F Yet Another Problem About Pairs Satisfying an Inequality
    时间限制\(2s\)|空间限制\(250M\)题目描述给你一个序列$a_1,a_2,\dotsa_n$。请计算出满足下面条件的$(i,j)(1\leqi,j\leqn)$个数。$a_i<i<a_j<j$.输入格式第一行包含一个整数$t$($1\leqt\leq1000$)—测试数据的个数每一个......
  • [Codeforces] CF1858C Yet Another Permutation Problem
    YetAnotherPermutationProblem-洛谷这题本来很简单,思路我也想到了,但是代码一直没写对,思路也一直换来换去(悲然而发现最开始的思路是对的题意Alex收到了一个名为"GCD排列"的游戏作为生日礼物。这个游戏的每一轮进行如下操作:首先,Alex选择一个整数序列\(a_1,a_2,…,a_......
  • [ABC327D] Good Tuple Problem 题解
    分析:这一道题很容易发现可以用并查集来维护(不知道为什么其他人都用了图论),\(a_i\)与其对应的\(b_i\)代表着\(a_i\)这个集合里不能存在着\(b_i\)。根据只有存在两个集合,所以我们会发现,若\(x\)与\(y\)不在一个集合且\(x\)与\(z\)也不在一个集合,那么\(x\)和\(y\)......
  • 洛谷 P4872 OIer们的东方梦 题解
    前言一个下午,一个晚上,一个早上,可以算是一天了吧,终于调出了这道题,纪念一下吧!!!食用更佳。这道题其实就是一道简简单单的BFS模(du)板(liu)题。说难不难,简单不简单,虽然没有难的算法,但是就是码量一百多行,比较难调。题目难度绿,思维难度橙,代码难度蓝。真是个绝世好题。题目意思就是一......
  • 洛谷P3161 [CQOI2012] 模拟工厂题解
    P3161[CQOI2012]模拟工厂题解。题目其实发现这是一道状压,发现这道题是一道数学题,其实就很简单了。对于每一次的订单我们可以设:\(time\)为距离下一个订单的时间。\(num\)为这个订单要生产的数量。\(x\)为生产能力。\(y\)的时间可以用来提高工厂的生产力。那我们就可以得......
  • 「杂题乱刷」洛谷P9515
    原题链接P9515「JOC-1A」限时签到题意简述有一条公路上有\(n\)个商店,每个商店分别在不同的时刻开放,求如何在\(t\)时刻之前到达\(f\)点并且到达最多开放的商店的数量,特别的,一个时刻只能走一格。解题思路这一道题是一道贪心题。首先,因为要在\(t\)时刻之前到达\(f\)......
  • 「杂题乱刷」洛谷P9253
    题目链接P9253[PA2022]Ornitolog2题目简述给定一个音高序列,输出最少要修改多少整数才能使这个序列成为交替鹡鸰鸟鸣的音高序列。题意分析操作后的音高序列总共有\(2\)种可能:音量由高变低再由低变高;音量由低变高再由高变低。又因为大小范围是\(10^4\times5......
  • 洛谷 P8955 「VUSC」Card Tricks
    洛谷传送门很显然每个数的每一位最多只会修改一遍。于是拆位,每一位开个并查集,存下一个不拥有这一位的数,就可以暴力修改了。但是空间是\(O(n\logV)\)的,炸了。于是可以考虑手写i24类,同时并查集寻找祖先不要用递归版的路径压缩,然后就过了。code//Problem:P8955「VUSC」......
  • CF1858C Yet Another Permutation Problem
    CF1858CYetAnotherPermutationProblemYetAnotherPermutationProblem-洛谷这题本来很简单,思路我也想到了,但是代码一直没写对,思路也一直换来换去(悲然而发现最开始的思路是对的题意Alex收到了一个名为"GCD排列"的游戏作为生日礼物。这个游戏的每一轮进行如下操作:......
  • git SSL certificate problem: unable to get local issuer certificate
    错误:gitSSLcertificateproblem:unabletogetlocalissuercertificate这个问题是由于没有配置信任的服务器HTTPS验证。默认,cURL被设为不信任任何CAs,就是说,它不信任任何服务器验证。解决方法gitconfig--globalhttp.sslVerifyfalse......