標籤:style blog http color os io strong for
今天又爆零了,又是又,怎麼又是又,爆零爆多了,又也就經常掛嘴邊了,看到這句話,你一定很想說一句””,弱菜被罵傻,也很正常啦。
如果你不開心,可以考慮往下看。
翻到E(HDU 4635 Strongly connected)題,這麼短的題目,肯定要先看啦。然後D(LightOJ 1229),然後C(ZOJ 2243),然後F(HDU 4711),然後B(CodeForces 385D),然後看A(HDU 3889)好吧,我承認,A題看了一眼就不看了,B題一看是線段什麼有點幾何的味道就果斷放棄,然後C題,傻傻的理解錯題意,提交一直WA,然後沒辦法,看E題,想到只要保證最後至少兩個連通分量,就可以滿足題意,然後要求最大值,那就保證有且僅有兩個連通分量就可以了,對於一個連通分量最多隻能有x(x-1)邊, x表示頂點數 ,然後得出一個式子,邊數f = n*n-n-1+x*x-(n+1)x;當x更(n+1)/2的差值越大,f越大,換句話說,只要把一個連通分量頂點個數最小的獨立出來,把其它的連通分量都合并成一個連通分量就可以了,
可是我沒考慮下面這種情況
這時候如果把3獨立出來,5、9、7弄成一個連通分量,那麼3也會跟5,9,7合并成一個連通分量,所以不能選3,
最小的不能選,那就選5吧,把3、7、9合并,可以。
也就是說是要把頂點個數盡量小且入度或者初度為零(一個連通分量看成一個點)的連通分量獨立出來。
view code#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <cmath>#include <vector>#include <map>#include <stack>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 100010;int _, cas=1, n, m;int in[N], out[N], num[N];vector<int > G[N];int pre[N], lowlink[N], dfs_clock, scc_cnt, sccno[N];stack<int >S;void dfs(int u){ pre[u] = lowlink[u] = ++dfs_clock; S.push(u); int siz = G[u].size(); for(int i=0; i<siz; i++) { int v = G[u][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 = S.top(); S.pop(); sccno[x] = scc_cnt; num[scc_cnt]++; if(x==u) break; } }}void find_scc(){ dfs_clock = 0; scc_cnt = 0; memset(sccno, 0, sizeof(sccno)); memset(pre, 0, sizeof(pre)); for(int i=1; i<=n; i++) { if(!pre[i]) dfs(i); }}void solve(){ scanf("%d%d", &n ,&m); memset(num, 0, sizeof(num)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); for(int i=1; i<=n ;i++) G[i].clear(); int u, v; for(int i=0; i<m; i++) { scanf("%d%d", &u, &v); G[u].push_back(v); } find_scc(); printf("Case %d: ", cas++); if(scc_cnt==1) { printf("-1\n"); return ; } ll ans = 0, Min = INF; for(int i=1; i<=n; i++) { int siz = G[i].size(); for(int j=0; j<siz; j++) { if(sccno[i]!=sccno[G[i][j]]) { in[sccno[G[i][j]]]++; out[sccno[i]]++; } } } for(int i=1; i<=scc_cnt; i++) { if((in[i]==0 || out[i]==0) && Min>num[i]) Min = num[i];// printf("num[%d] = %d\n", i, num[i]);// printf("out = %d, in = %d\n", out[i], in[i]); } ans = (Min-1)*Min- m + (n-Min)*(n-Min-1)+Min*(n-Min); cout<<ans<<endl;}int main(){// freopen("in", "r", stdin); cin>>_; while(_--) solve(); return 0;}
紅色部分就是思維漏洞
。差一點,不過acm沒有差一點,只有ac或者沒ac.
下面再來總結一下題目吧
Problem A
HDU 3889(水題,不會做)
Problem B
CodeForces 385D(dp,題意尚不明確)
Problem C
ZOJ 2243(什麼treap,被坑)
Problem D
LightOJ 1229(博弈,不會)
Problem E
HDU 4635(。。。。。。。。。。。。。。。。。,此處省略一萬字)
Problem F
HDU 4711 。。