BZOJ 4078: [Wf2014]Metal Processing Plant [放弃了]

以后再也不做$World Final$的题了................

还我下午

bzoj上TLE一次后就不敢交了然后去uva交

Claris太神了代码完全看不懂

还有一个代码uva上竟然WA了我也不知道怎么回事....

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=405,INF=2e9;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,w[201][201];
int a[200*200+5];
struct edge{
    int v,ne;
}e[N*N];
int h[N],cnt=0;
inline void ins(int u,int v){
    cnt++;
    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
int dfn[N],low[N],dfc,belong[N],scc;
int st[N],top;
void dfs(int u){
    dfn[u]=low[u]=++dfc;
    st[++top]=u;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[u],low[v]);
        }else if(!belong[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scc++;int x=0;
        while(x!=u){
            x=st[top--];
            belong[x]=scc;
        }
    }
}
bool judge(){
    for(int i=1;i<=n;i++) 
        if(belong[(i<<1)-1]==belong[i<<1]) return false;
    return true;
}
int A,B;
bool check(){
    cnt=0;int _=n<<1;
    for(int i=1;i<=_;i++) h[i]=dfn[i]=low[i]=belong[i]=0;dfc=scc=0;
    for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++){
            int x=i<<1,y=j<<1,val=w[i][j];
            if(A<val&&val<=B) ins(x-1,y),ins(y-1,x);
            else if(val>B) ins(x-1,y),ins(x,y-1),ins(y-1,x),ins(y,x-1);
        }
    for(int i=1;i<=_;i++) if(!dfn[i]) dfs(i);
    return judge();
}
int ans;
void solve(){
    int head=1,tail=m;
    while(head<=tail){
        A=a[head];B=a[tail];
        while(head<=tail&&check()){
            ans=min(ans,A+B);
            B=a[--tail];
        }
        head++;
    }
}
void solve1(){
    for(int i=1;i<=m;i++){printf("A %d\n",i);
        A=a[i];if((A<<1)>ans) break;
        int l=i,r=m,t=INF;
        while(l<=r){
            int mid=(l+r)>>1;
            B=a[mid];
            if(check()) t=B,r=mid-1;
            else l=mid+1;
        }
        ans=min(ans,A+t);
    }
}
int main(){
    freopen("in","r",stdin);
    while(scanf("%d",&n)!=EOF){
        ans=INF;
        m=0;
        if(n<=2) {puts("0");return 0;}
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++) 
                w[i][j]=w[j][i]=read(),a[++m]=w[i][j];
        sort(a+1,a+1+m);
        solve();
        printf("%d\n",ans);
    }
}

 

posted @ 2017-02-22 17:56  Candy?  阅读(809)  评论(0编辑  收藏  举报