HDU 4005 The war(边双连通+缩点)

来源:互联网 发布:网络销售彩票好做吗 编辑:程序博客网 时间:2024/04/29 02:40

题意:有一幅图,现在要加一条边,加边之后要你删除一条边,使图不连通,费用为边的费用,要你求的是删除的边的最小值的最大值(每次都可以删除一条边,选最小的删除,这些最小中的最大就为答案)。

思路:首先求出桥边然后缩点,这时候得到了一棵树,因为树上任意两点之间连一条线会形成一条环,所以我们就想使得环以外的最小边尽可能大。

首先考虑最小边,最小边一定在这个环上,然后以这条最小边的两个端点进行dfs,找出以这两个端点为根到子树的路径中的次小值,然后取两个次小值中的较小者就是答案。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 10010;//点数const int MAXM = 200010;//边数int n, m;struct Edge{    int to, next, w;}edge[MAXM];int head[MAXN], tot;int Low[MAXN], DFN[MAXN], Stack[MAXN], Belong[MAXN];//Belong数组的值是1~Blockint Index, Top;int Block;//边双连通块数bool Instack[MAXN];vector<int> G[MAXN], W[MAXN]; //缩点后形成的图 bool tag;int node1, node2, minedge, ans;void addedge(int u,int v,int w){    edge[tot].to = v;edge[tot].next = head[u];edge[tot].w = w;    head[u] = tot++;}void init(){memset(head,-1,sizeof(head));memset(DFN,0,sizeof(DFN));    memset(Instack,false,sizeof(Instack));    tag = Index = Top = Block = tot = 0;    minedge = INF;    ans = INF;for(int i = 1; i <= n; i++) G[i].clear(), W[i].clear();}void Tarjan(int u,int id){    int v;    Low[u] = DFN[u] = ++Index;    Stack[Top++] = u;    Instack[u] = true;    for(int i = head[u];i != -1;i = edge[i].next)    {        v = edge[i].to;        if((i^1) == id) continue; if( !DFN[v] )        {            Tarjan(v, i);            if( Low[u] > Low[v] )Low[u] = Low[v];        }        else if( Instack[v] && Low[u] > DFN[v])            Low[u] = DFN[v];    }    if(Low[u] == DFN[u])    {        Block++;        do        {            v = Stack[--Top];            Instack[v] = false;            Belong[v] = Block;        }        while( v!=u );    }}void suodian() {for(int i = 1; i <= n; i++) {for(int e = head[i]; e != -1; e = edge[e].next) {int u = edge[e].to, w = edge[e].w;if(Belong[u] != Belong[i]) {G[Belong[i]].push_back(Belong[u]);W[Belong[i]].push_back(w);if(w < minedge) {minedge = w;node1 = Belong[i], node2 = Belong[u];}tag = 1;}}}}int dfs(int cur, int fa) {int min1 = INF, min2 = INF;for(int i = 0; i < G[cur].size(); i++) {int u = G[cur][i];if(u == fa) continue;int tmp = dfs(u, cur);tmp = min(tmp, W[cur][i]);if(tmp < min1) min2 = min1, min1 = tmp;else if(tmp < min2) min2 = tmp;}ans = min(ans, min2);return min1;}int main() {    //freopen("input.txt", "r", stdin);while(cin >> n >> m) {init();for(int i = 1, u, v, d; i <= m; i++) {scanf("%d%d%d", &u, &v, &d);addedge(u, v, d);addedge(v, u, d);}Tarjan(1, -1);suodian();if(!tag) {puts("-1");continue;}dfs(node1, node2);dfs(node2, node1);if(ans == INF) puts("-1");else cout << ans << endl; }    return 0;} 


0 0
原创粉丝点击