hdu4005The war

来源:互联网 发布:windows apm命令 编辑:程序博客网 时间:2024/06/07 01:52

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4005

题意:给定n个点m条边的无向图,求任意添加一条边后的最小割边的最大值。

分析:因为是图很明显我们要先缩点将图缩成一颗树,然后会发现题目变成在树上添加一条边求最小不在环上的最大值。很显然那个最大值应该尽量不和最小边在一条链上,那么我们以最小边为根dfs确定一条链尽可能将小边包含使得不在链上的边的最小值最大。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=10010;const int M=100010;const int mod=1000000007;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=1004535809;const int INF=1000000010;const ll MAX=1ll<<55;const double eps=1e-5;const double inf=~0u>>1;const double pi=acos(-1.0);typedef long double db;typedef unsigned int uint;typedef unsigned long long ull;struct Edge {    int u,v,w,id,nex;    Edge() {}    Edge(int u,int v,int w,int id,int nex):u(u),v(v),w(w),id(id),nex(nex) {}}edge[M<<1];int ans,tot,first[N];int sccn,dfs_clock,pre[N],dfn[N],vis[M],sccno[N];void dfs(int u) {    pre[u]=dfn[u]=++dfs_clock;    for (int i=first[u];~i;i=edge[i].nex)    if (!vis[edge[i].id]) {        vis[edge[i].id]=1;        if (!pre[edge[i].v]) {            dfs(edge[i].v);            dfn[u]=min(dfn[u],dfn[edge[i].v]);            if (dfn[edge[i].v]>pre[u]) vis[edge[i].id]=2;        } else dfn[u]=min(dfn[u],pre[edge[i].v]);    }}void dfs_num(int u) {    sccno[u]=sccn;    for (int i=first[u];~i;i=edge[i].nex)    if (vis[edge[i].id]==1&&!sccno[edge[i].v]) {        vis[edge[i].id]=0;dfs_num(edge[i].v);    }}void dfs_scc(int n,int m) {    sccn=dfs_clock=0;    for (int i=1;i<=m;i++) vis[i]=0;    for (int i=1;i<=n;i++) pre[i]=sccno[i]=0;    for (int i=1;i<=n;i++)    if (!pre[i]) dfs(i);    for (int i=1;i<=n;i++)    if (!sccno[i]) sccn++,dfs_num(i);}struct node {    int v,w;    node() {}    node(int v,int w):v(v),w(w) {}};vector<node>V[N];void dfs(int u,int v,int w) {    int i;dfn[u]=0;    for (i=0;i<V[u].size();i++)    if (V[u][i].v!=v) {        dfs(V[u][i].v,u,V[u][i].w);        if (pre[V[u][i].v]<pre[dfn[u]]) dfn[u]=V[u][i].v;    }    pre[u]=min(w,pre[dfn[u]]);}void dfs_ans(int u,int v,int w,int bo) {    if (!bo) ans=min(ans,w);    for (int i=0;i<V[u].size();i++)    if (V[u][i].v!=v) {        if (V[u][i].v==dfn[u]) dfs_ans(V[u][i].v,u,V[u][i].w,bo);        else dfs_ans(V[u][i].v,u,V[u][i].w,0);    }}int main(){    int i,n,m,u,v,w,mi;    while (scanf("%d%d", &n, &m)!=EOF) {        for (tot=0,i=1;i<=n;i++) first[i]=-1;        for (i=1;i<=m;i++) {            scanf("%d%d%d", &u, &v, &w);            edge[tot]=Edge(u,v,w,i,first[u]);first[u]=tot++;            edge[tot]=Edge(v,u,w,i,first[v]);first[v]=tot++;        }        dfs_scc(n,m);        u=v=0;mi=INF;        for (i=1;i<=sccn;i++) V[i].clear();        for (i=0;i<tot;i+=2)        if (sccno[edge[i].u]!=sccno[edge[i].v]) {            V[sccno[edge[i].u]].push_back(node(sccno[edge[i].v],edge[i].w));            V[sccno[edge[i].v]].push_back(node(sccno[edge[i].u],edge[i].w));            if (edge[i].w<mi) mi=edge[i].w,u=sccno[edge[i].u],v=sccno[edge[i].v];        }        ans=pre[0]=INF;        dfs(u,v,INF);dfs(v,u,INF);        dfs_ans(u,v,w,1);dfs_ans(v,u,w,1);        if (ans==INF) printf("-1\n");        else printf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击