• BZOJ1093: [ZJOI2007]最大半连通子图


    1093: [ZJOI2007]最大半连通子图

    Time Limit: 30 Sec  Memory Limit: 162 MB
    Submit: 1530  Solved: 589
    [Submit][Status]

    Description

    Input

    第一行包含两个整数N,M,X。N,M分别表示图G的点数与边数,X的意义如上文所述。接下来M行,每行两个正整数a, b,表示一条有向边(a, b)。图中的每个点将编号为1,2,3…N,保证输入中同一个(a,b)不会出现两次。

    Output

    应包含两行,第一行包含一个整数K。第二行包含整数C Mod X.

    Sample Input

    6 6 20070603
    1 2
    2 1
    1 3
    2 4
    5 6
    6 4

    Sample Output

    3
    3

    HINT

    对于20%的数据, N ≤18;对于60%的数据, N ≤10000;对于100%的数据, N ≤100000, M ≤1000000;对于100%的数据, X ≤10^8。

    Source

    题解:

    按输入构图,tarjan缩点之后变为DAG,最大节点数即为“最长链”,一条链的长度定义为所有节点的权值之和,每个scc的权值为它的节点个数

    最长链的求法类似于拓扑排序+DP

    求构成方案只要在取max的时候判断一下即可,利用加法原理

    答案扫一遍即可(ms也可以加一个虚拟节点,由所有scc向它连边,然后最后直接输出该点的信息就行。。。)

    本题还有一个注意的地方就是tarjan之后重构图的时候会加入重边,要消除重边的影响可以在topsort的时候对访问过的节点做一下标记

    具体实现见代码

    代码:

    1.

      1 const maxn=110000+1000;maxm=1100000+1000;
      2 type node=record
      3      from,go,next:longint;
      4      end;
      5 var e:array[0..maxm] of node;
      6     e2:array[0..maxm] of node;
      7     a,b:array[0..maxm] of longint;
      8     n,m,h,t,x,y,i,ti,top,cnt,ans1,ans2,tot,p:longint;
      9     q,head,head2,dfn,low,sta,scc,s,v,num,inp,vis:array[0..maxn] of longint;
     10     function min(x,y:longint):longint;
     11      begin
     12      if x<y then exit(x) else exit(y);
     13      end;
     14 
     15 procedure insert(x,y:longint);
     16  begin
     17  inc(tot);
     18  e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
     19  end;
     20 procedure insert2(x,y:longint);
     21  begin
     22  inc(tot);
     23  e2[tot].go:=y;e2[tot].next:=head2[x];head2[x]:=tot;
     24  end;
     25 procedure dfs(x:longint);
     26  var i,y,z:longint;
     27  begin
     28  inc(ti);dfn[x]:=ti;low[x]:=ti;inc(top);sta[top]:=x;
     29  i:=head[x];
     30  while i<>0 do
     31   begin
     32    y:=e[i].go;
     33    if dfn[y]=0 then
     34     begin
     35     dfs(y);
     36     low[x]:=min(low[x],low[y]);
     37     end
     38    else if scc[y]=0 then low[x]:=min(low[x],dfn[y]);
     39   i:=e[i].next;
     40   end;
     41  if low[x]=dfn[x] then
     42   begin
     43   inc(cnt);
     44   while true do
     45    begin
     46    z:=sta[top];dec(top);
     47    scc[z]:=cnt;inc(s[cnt]);
     48    if z=x then break;
     49    end;
     50   end;
     51  end;
     52 procedure tarjan;
     53  begin
     54  ti:=0;cnt:=0;ti:=0;
     55  fillchar(dfn,sizeof(dfn),0);
     56  for i:=1 to n do if dfn[i]=0 then dfs(i);
     57  end;
     58 procedure init;
     59  begin
     60    readln(n,m,p);
     61    for i:=1 to m do
     62     begin
     63      readln(a[i],b[i]);
     64      insert(a[i],b[i]);
     65     end;
     66  end;
     67 procedure main;
     68  begin
     69    tarjan;
     70    fillchar(inp,sizeof(inp),0);tot:=0;
     71    for i:=1 to m do
     72     begin
     73     x:=scc[a[i]];y:=scc[b[i]];
     74     if x<>y then begin inc(inp[y]);insert2(x,y);end;
     75     end;
     76    h:=0;t:=0;
     77    for i:=1 to cnt do
     78     if inp[i]=0 then begin inc(t);q[t]:=i;v[i]:=s[i];num[i]:=1;end;
     79    while h<t do
     80     begin
     81     inc(h);x:=q[h];
     82     i:=head2[x];
     83     while i<>0 do
     84      begin
     85      y:=e2[i].go;
     86      if vis[y]<>x then
     87       begin
     88       vis[y]:=x;
     89       if v[x]+s[y]>v[y] then begin v[y]:=v[x]+s[y];num[y]:=num[x];end
     90       else if v[x]+s[y]=v[y] then num[y]:=(num[y]+num[x]) mod p;
     91       end;
     92      dec(inp[y]);if inp[y]=0 then begin inc(t);q[t]:=y;end;
     93      i:=e2[i].next;
     94      end;
     95     end;
     96    ans1:=0;ans2:=0;
     97    for i:=1 to cnt do if v[i]>ans1 then begin ans1:=v[i];ans2:=num[i];end
     98    else if v[i]=ans1 then ans2:=(ans2+num[i]) mod p;
     99    writeln(ans1);
    100    writeln(ans2);
    101  end;
    102 begin
    103   assign(input,'input.txt');assign(output,'output.txt');
    104   reset(input);rewrite(output);
    105   init;
    106   main;
    107   close(input);close(output);
    108 end.   
    View Code

    2.加虚拟节点

      1 const maxn=110000+1000;maxm=1100000+1000;
      2 type node=record
      3      from,go,next:longint;
      4      end;
      5 var e:array[0..maxm] of node;
      6     e2:array[0..2*maxm] of node;
      7     a,b:array[0..maxm] of longint;
      8     n,m,h,t,x,y,i,ti,top,cnt,ans1,ans2,tot,p:longint;
      9     q,head,head2,dfn,low,sta,scc,s,v,num,inp,vis:array[0..maxn] of longint;
     10     function min(x,y:longint):longint;
     11      begin
     12      if x<y then exit(x) else exit(y);
     13      end;
     14 
     15 procedure insert(x,y:longint);
     16  begin
     17  inc(tot);
     18  e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
     19  end;
     20 procedure insert2(x,y:longint);
     21  begin
     22  inc(tot);
     23  e2[tot].go:=y;e2[tot].next:=head2[x];head2[x]:=tot;
     24  end;
     25 procedure dfs(x:longint);
     26  var i,y,z:longint;
     27  begin
     28  inc(ti);dfn[x]:=ti;low[x]:=ti;inc(top);sta[top]:=x;
     29  i:=head[x];
     30  while i<>0 do
     31   begin
     32    y:=e[i].go;
     33    if dfn[y]=0 then
     34     begin
     35     dfs(y);
     36     low[x]:=min(low[x],low[y]);
     37     end
     38    else if scc[y]=0 then low[x]:=min(low[x],dfn[y]);
     39   i:=e[i].next;
     40   end;
     41  if low[x]=dfn[x] then
     42   begin
     43   inc(cnt);
     44   while true do
     45    begin
     46    z:=sta[top];dec(top);
     47    scc[z]:=cnt;inc(s[cnt]);
     48    if z=x then break;
     49    end;
     50   end;
     51  end;
     52 procedure tarjan;
     53  begin
     54  ti:=0;cnt:=0;ti:=0;
     55  fillchar(dfn,sizeof(dfn),0);
     56  for i:=1 to n do if dfn[i]=0 then dfs(i);
     57  end;
     58 procedure init;
     59  begin
     60    readln(n,m,p);
     61    for i:=1 to m do
     62     begin
     63      readln(a[i],b[i]);
     64      insert(a[i],b[i]);
     65     end;
     66  end;
     67 procedure main;
     68  begin
     69    tarjan;
     70    fillchar(inp,sizeof(inp),0);tot:=0;
     71    for i:=1 to m do
     72     begin
     73     x:=scc[a[i]];y:=scc[b[i]];
     74     if x<>y then begin inc(inp[y]);insert2(x,y);end;
     75     end;
     76    for i:=1 to cnt do insert2(i,cnt+1);
     77    inp[cnt+1]:=cnt;s[cnt+1]:=0;
     78    h:=0;t:=0;
     79    for i:=1 to cnt do
     80     if inp[i]=0 then begin inc(t);q[t]:=i;v[i]:=s[i];num[i]:=1;end;
     81    while h<t do
     82     begin
     83     inc(h);x:=q[h];
     84     i:=head2[x];
     85     while i<>0 do
     86      begin
     87      y:=e2[i].go;
     88      if vis[y]<>x then
     89       begin
     90       vis[y]:=x;
     91       if v[x]+s[y]>v[y] then begin v[y]:=v[x]+s[y];num[y]:=num[x];end
     92       else if v[x]+s[y]=v[y] then num[y]:=(num[y]+num[x]) mod p;
     93       end;
     94      dec(inp[y]);if inp[y]=0 then begin inc(t);q[t]:=y;end;
     95      i:=e2[i].next;
     96      end;
     97     end;
     98    writeln(v[cnt+1]);
     99    writeln(num[cnt+1]);
    100  end;
    101 begin
    102   assign(input,'input.txt');assign(output,'output.txt');
    103   reset(input);rewrite(output);
    104   init;
    105   main;
    106   close(input);close(output);
    107 end.                         
    View Code
  • 相关阅读:
    [剑指offer] 42. 和为S的两个数字
    [剑指offer] 41. 和为S的连续正数序列
    datagridview bindingsource刷新数据
    datagridview bindingsource
    slot-具名插槽
    基于uniapp的ui库
    组件之间通讯
    vue实现word或pdf文档导出的功能
    Vue之富文本tinymce爬坑录
    12道vue高频原理面试题,你能答出几道?
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3904679.html
Copyright © 2020-2023  润新知