給定n個點m條邊的無向圖,每條邊有兩個權值a與b。求一條1到n的路徑使得路徑經過邊的最大a與最大b的和最小。無法到達輸出-1。
n<=50000,m<=100000。
我們嘗試列舉路徑的最大a值,那麼我們只需按照a排序按順序插入,維護1到n的b最大值即可。
用並查集維護連通性。當加入j到k這條邊時如果形成環,則刪除環上的最大值。
我們用動態樹來進行維護。
為了實現更易,將每條邊看做乙個點,例如第i條邊兩個端點是j與k,那麼將i+n與j、k相連,權值放在代表邊的點上。
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using
namespace
std;
const
int maxn=50000+10;
stack
sta;
struct dong;
dong e[maxn*2];
int tree[maxn*3][2],key[maxn*3],father[maxn*3],num[maxn*3],pp[maxn*3],fa[maxn];
int i,j,k,l,t,n,m,ans;
bool bz[maxn*3];
int max(int a,int b)
int pd(int x)
void update(int x)
void rotate(int x)
void clear(int x)
}void romove(int x,int y)
while (!sta.empty())
}void splay(int x,int y)
}void access(int x)
}void makeroot(int x)
void link(int x,int y)
void cut(int x,int y)
int getfa(int x)
bool cmp(dong a,dong b)
else
//printf("%d\n",i);
continue;}}
else fa[getfa(k)]=getfa(j);
key[i+n]=e[i].b;
num[i+n]=i+n;
link(i+n,j);
link(i+n,k);
if (getfa(1)==getfa(n))
//printf("%d\n",i);
}if (ans==10000000) ans=-1;
printf("%d\n",ans);
}
bzoj 3669 Noi2014 魔法森林
description 為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在1號節點,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有...
bzoj 3669 NOI2014 魔法森林
為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在號節點1,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有人經過一條邊的時候,這條...
BZOJ3669 NOI2014魔法森林
按a從小到大排序,然後按b建圖。每次只需要找1 n中最大的b加當前的a計算答案即可。這裡還有乙個小操作就是化邊為點,把一條邊的邊權看做乙個點的點權然後多連兩條邊。by 大奕哥 1 include2 using namespace std 3const int n 4e5 10 4 int fa n ...