[CC-LONCYC]Lonely Cycles

來源:互聯網
上載者:User

標籤:clear   ons   包含   turn   math   ==   ret   mes   getchar   

[CC-LONCYC]Lonely Cycles題目大意:

\(T(T\le1000)\)組資料。

給定一張簡單圖(不含重邊與自環),圖中有\(n(n\le2\times10^5)\)個節點和\(m(\sum n+m\le5\times10^6)\)條邊。每個節點最多屬於一個簡單環。

對於每條邊,求出有多少簡單路徑包含這條邊且至多包含一條在簡單環上的邊。

思路:

縮點後根據是否為環上邊討論,環上邊的方案數就是兩邊結點數之積。去掉這些環就只剩下若干棵樹,可以樹形DP。

原始碼:
#include<stack>#include<cstdio>#include<cctype>#include<vector>inline int getint() {    register char ch;    while(!isdigit(ch=getchar()));    register int x=ch^'0';    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');    return x;}typedef long long int64;const int N=2e5+1,M=5e6;struct Edge2 {    int u,v,id;};Edge2 edge[M];struct Edge {    int to,id;};std::vector<Edge> e[N];inline void add_edge(const int &u,const int &v,const int &id) {    e[u].push_back((Edge){v,id});    e[v].push_back((Edge){u,id});}bool ins[N],vis[N];std::stack<int> s;int dfn[N],low[N],scc[N],size[N],top[N],par[N],sum[N];int64 ans[M];void tarjan(const int &x,const int &par) {    s.push(x);    ins[x]=true;    dfn[x]=low[x]=++dfn[0];    for(auto &j:e[x]) {        const int &y=j.to;        if(y==par) continue;        if(!dfn[y]) {            tarjan(y,x);            low[x]=std::min(low[x],low[y]);        } else if(ins[y]) {            low[x]=std::min(low[x],dfn[y]);        }    }    if(dfn[x]==low[x]) {        scc[0]++;        int y;        do {            y=s.top();            s.pop();            ins[y]=false;            scc[y]=scc[0];        } while(y!=x);    }}void dfs(const int &x,const int &par) {    ::par[x]=par;    size[x]=vis[x]=1;    top[x]=par?top[par]:x;    for(auto &j:e[x]) {        const int &y=j.to;        if(y==par||scc[x]==scc[y]) continue;        dfs(y,x);        size[x]+=size[y];    }}void dp1(const int &x) {    for(auto &j:e[x]) {        const int &y=j.to;        if(y==par[x]||top[x]!=top[y]) continue;        dp1(y);        sum[x]+=sum[y];    }}void dp2(const int &x) {    for(auto &j:e[x]) {        const int &y=j.to,&id=j.id;        if(y==par[x]||top[x]!=top[y]) continue;        dp2(y);        ans[id]+=(int64)(size[top[x]]-size[y])*size[y];        ans[id]+=(int64)(sum[top[x]]-sum[y])*size[y];        ans[id]+=(int64)sum[y]*(size[top[x]]-size[y]);    }}int main() {    for(register int T=getint();T;T--) {        const int n=getint(),m=getint();        for(register int i=0;i<m;i++) {            edge[i].u=getint();            edge[i].v=getint();            edge[i].id=i;            add_edge(edge[i].u,edge[i].v,i);        }        for(register int i=1;i<=n;i++) {            if(!dfn[i]) tarjan(i,0);        }        for(register int i=1;i<=n;i++) {            if(!vis[i]) dfs(i,0);        }        for(register int i=0;i<m;i++) {            const int &u=edge[i].u,&v=edge[i].v;            if(scc[u]!=scc[v]) continue;            ans[i]=(int64)size[top[u]]*size[top[v]];            sum[u]+=size[top[v]];            sum[v]+=size[top[u]];        }        for(register int i=1;i<=n;i++) {            if(i==top[i]) dp1(i);        }        for(register int i=1;i<=n;i++) {            if(i==top[i]) dp2(i);        }        for(register int i=0;i<m;i++) {            printf("%lld\n",ans[i]);        }        //Reset        for(register int i=1;i<=n;i++) {            e[i].clear();        }        std::fill(&sum[1],&sum[n]+1,0);        std::fill(&dfn[0],&dfn[n]+1,0);        std::fill(&ans[0],&ans[m],0);        std::fill(&vis[1],&vis[n]+1,false);        scc[0]=0;    }    return 0;}

[CC-LONCYC]Lonely Cycles

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.