(題目鏈結)
給出一張帶權圖,每條邊有兩個權值a和b,一條路徑的花費為路徑中的最大的a和最大的b之和。求從1走到n的最小花費。
列舉a,spfa鬆弛。
不得不說uoj的hack還是很強力的,仔細想了想,資料好像也並不是特別難構。只要使每次加邊都必須遍歷整張圖,之前n都未連通,最後一條a最大的邊連向n即可。
// uoj3#include#include#include#include#include#include#include#include#include#define ll long long
#define inf (1ll<<30)
#define pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
const int maxn=50010,maxm=100010;
int head[maxn],dis[maxn],fa[maxn],vis[maxn],n,m,cnt;
struct data a[maxm];
struct edge e[maxm<<1];
void link(int u,int v,int wa,int wb) ;head[u]=cnt;
e[++cnt]=(edge);head[v]=cnt;
}int find(int x)
bool cmp(data a,data b)
} ans=min(ans,a[i].wa+dis[n]);
if ((double)clock()/clocks_per_sec>=2.8) break;
} printf("%d\n",ans);
return 0;
}
link cut tree維護最小生成樹。把邊權轉為點權表示。每次加邊時,如果$$在乙個連通塊內,查詢連通塊中點權最大值,如果大於當前邊的邊權,就把這個點刪掉。每次加完一條邊後,如果起點和終點在同一連通塊中,就更新下答案。
// uoj2#include#include#include#include#include#include#define ll long long
#define inf (1ll<<30)
#define pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
const int maxn=200010;
int a[maxn],tr[maxn][2],rev[maxn],fa[maxn],mx[maxn];
int n,m;
struct edge
} if (find(1)==find(n)) ans=min(ans,e[i].wa+a[query(1,n)]);
} printf("%d",ans==inf ? -1 : ans);
return 0;
}
NOI2014 魔法森林
為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為 1 n 邊標號為1 m 初始時小e同學在 1 號節點,隱士則住在 n 號節點。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有人經過一條邊的...
NOI2014 魔法森林
為了得到書法大家的真傳,小 e 同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含 n 個節點 m 條邊的無向圖,節點標號為1,2,3,n,邊標號為 1,2,3,m。初始時小 e 同學在 1 號節點,隱士則住在 n 號節點。小 e 需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中...
NOI2014 魔法森林
noi2014 魔法森林 要求a 與 b 的總和最小 可以按a排序 再以b為權值維護一顆樹 lct維護最小生成樹 要解決的問題 將每一條邊變為乙個點 邊權變為點權 舉個栗子 u v有一條邊權為w的邊 怎lct連邊方式為 u new v new的點權為w 不斷維護最小生成樹 如果新加入的邊的 u與v不...