「國慶訓練」Bomb(HDU-5934)

來源:互聯網
上載者:User

標籤:不為   main   fabs   stream   push   air   這一   建圖   with   

題意

給定\(n\)個炸彈,每個炸彈的座標與代價與影響範圍給定,炸彈會引爆影響範圍內其他所有炸彈。求引爆所有炸彈的最小代價。

分析

先做\(n^2\)的迴圈,然後建圖,對\(i\)能引爆\(j\)建邊\((i,j)\)。然後對這個圖求強連通分量並縮點,構成新的有向無環的森林。定義每個強連通分量的cost為其中包含的點的最小cost,然後把新森林中所有入度為0的點的cost加起來求和即可(由於無環,所以從任何入度不為0的點往回走,必然終止於一個入度為0的點)。

代碼
#include <iostream>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <vector>#include <set>#include <map>#include <queue>#include <stack>#define MP make_pair#define PB push_back#define fi first#define se second#define ZERO(x) memset((x), 0, sizeof(x))#define ALL(x) (x).begin(),(x).end()#define rep(i, a, b) for (int i = (a); i <= (b); ++i)#define per(i, a, b) for (int i = (a); i >= (b); --i)#define QUICKIO                      ios::sync_with_stdio(false);     cin.tie(0);                      cout.tie(0);#define MS(x,y) memset(x,y,sizeof(x))#define int llusing namespace std;typedef long long ll;const int MAXN=1005;vector<int> G[MAXN];bool mat[MAXN][MAXN];int n;int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;stack<int> stk;void dfs(int u){    pre[u]=lowlink[u] = ++dfs_clock;    stk.push(u);    rep(i,0,n-1)    {        if(!mat[u][i]) continue;         int v=i;        if(!pre[v])        {            dfs(v);            lowlink[u]=min(lowlink[u],lowlink[v]);        }        else if(!sccno[v])        {            lowlink[u]=min(lowlink[u],pre[v]);        }    }    if(lowlink[u]==pre[u])    {        scc_cnt++;        for(;;)        {            int x=stk.top(); stk.pop();            sccno[x]=scc_cnt;            if(x==u) break;        }    }}void find_scc(){    dfs_clock=scc_cnt=0;    ZERO(sccno);    ZERO(pre);    rep(i,0,n-1)        if(!pre[i]) dfs(i);}bool nmat[MAXN][MAXN];vector<pair<int,int> > edges;vector<int> nG[MAXN];int ncnt=0;void add_edges(int u,int v){    edges.PB(MP(u,v));    nG[u].PB(edges.size()-1);}pair<int,int> pnt[MAXN];int pntc[MAXN], pntr[MAXN];inline double dist(int x,int y){    return sqrt((pnt[x].fi-pnt[y].fi)*(pnt[x].fi-pnt[y].fi)+                (pnt[x].se-pnt[y].se)*(pnt[x].se-pnt[y].se));}int cost[MAXN];signed main(){    int T; scanf("%lld", &T);    rep(kase,1,T)    {        ZERO(nmat);        ZERO(mat);        scanf("%lld", &n);        rep(i,1,n)        {            int x,y;            scanf("%lld%lld%lld%lld", &x,&y, &pntr[i], &pntc[i]);            pnt[i]=MP(x,y);        }        rep(i,1,n)        {            rep(j,1,n)            {                if(i==j) continue;                double d=pntr[i]-dist(i,j);                if(fabs(d)<1e-6 || d>1e-6)                {                    mat[i-1][j-1]=true;                }            }        }        /*        rep(i,0,n-1)        {            rep(j,0,n-1)                cout<<mat[i][j]<<" ";            cout<<endl;        }        */        find_scc();        memset(cost,0x3f,sizeof(cost));        rep(i,1,n)        {            cost[sccno[i-1]]=min(cost[sccno[i-1]],pntc[i]);        }        rep(i,0,n-1)        {            rep(j,0,n-1)            {                if(i==j) continue;                nmat[sccno[i]][sccno[j]]|=                    mat[i][j];            }        }        /*        rep(i,1,scc_cnt)        {            rep(j,1,scc_cnt)                cout<<nmat[i][j]<<" ";            cout<<endl;        }        */        ll ans=0;        /*        rep(i,0,n-1) cout<<sccno[i]<<" ";        cout<<endl;        rep(i,0,n-1) cout<<cost[i]<<" ";        cout<<endl;        */                rep(i,1,scc_cnt)        {            int ok=0;            rep(j,1,scc_cnt)            {                if(i==j) continue;                if(nmat[j][i])                {                    ok++;                    break;                }            }            if(!ok)            {                //cout<<i<<" "<<cost[i]<<endl;                ans+=cost[i];            }        }        printf("Case #%lld: %lld\n", kase, ans);    }    return 0;}
劄記

這題是在一場訓練賽中打的。當時的我們激情卡題兩個半小時23333然後我覺得不行了只能換題,不懂圖論的隊友說了這題可以寫,他覺得是帶權並查集23333我想了一下,這一看就是縮點啊。然後縮點之後沒什麼好辦法,不過也沒浪費時間——他們還在卡題23333過了又是半個小時,他們終於出了另外一題(卡的那個簽到題還是沒出!!!),這個時候還剩下一個半小時了,我想到可以求和入度為0的點即可。然後又過去半個小時(出簽到題啊啊啊啊啊)沒出(- -|||),只好我上寫這題,然後半個小時寫完,5分鐘調試,交上去WA,看了下代碼,改了個long long,過了。後來那個簽到題成功出了(太真實了),我們翻盤大成功,哇哢哢~

「國慶訓練」Bomb(HDU-5934)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.