编程介的小学生 2017-11-16 12:47 采纳率: 20.5%
浏览 612
已结题

Strongly connected

Problem Description
Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a simple directed graph. Also, after you add these edges, this graph must NOT be strongly connected.
A simple directed graph is a directed graph having no multiple edges or graph loops.
A strongly connected digraph is a directed graph in which it is possible to reach any node starting from any other node by traversing edges in the direction(s) in which they point.

Input
The first line of date is an integer T, which is the number of the text cases.
Then T cases follow, each case starts of two numbers N and M, 1<=N<=100000, 1<=M<=100000, representing the number of nodes and the number of edges, then M lines follow. Each line contains two integers x and y, means that there is a edge from x to y.

Output
For each case, you should output the maximum number of the edges you can add.
If the original graph is strongly connected, just output -1.

Sample Input
3
3 3
1 2
2 3
3 1
3 3
1 2
2 3
1 3
6 6
1 2
2 3
3 1
4 5
5 6
6 4

Sample Output
Case 1: -1
Case 2: 1
Case 3: 15

  • 写回答

1条回答 默认 最新

  • Traveling_DING 2018-08-07 02:06
    关注

    #include
    #include
    #include
    #include
    using namespace std;
    const int N = 100005;
    const int M = 200005;
    const int INF = 0xffffffff;
    typedef long long ll;
    int n, m, cnt, head[N];
    int dep, top, atype;
    int dfn[N], low[N], Stack[N], belong[N], in[N], out[N], sum[N];
    bool vis[N];
    struct Edge
    {
    int to, nxt;
    }edge[M];
    void addedge(int u, int v)
    {
    edge[cnt].to = v;
    edge[cnt].nxt = head[u];
    head[u] = cnt++;
    }
    void Tarjan(int u)
    {
    dfn[u] = low[u] = ++dep;
    Stack[top++] = u;
    vis[u] = true;
    for(int i = head[u]; i != -1; i = edge[i].nxt)
    {
    int v = edge[i].to;
    if(!dfn[v])
    {
    Tarjan(v);
    low[u] = min(low[u], low[v]);
    }
    else if(vis[v])
    low[u] = min(low[u], dfn[v]);
    }
    int j;
    if(dfn[u] == low[u])
    {
    atype++;
    do
    {
    j = Stack[--top];
    belong[j] = atype;
    sum[atype]++;
    vis[j] = false;
    }
    while(u != j);
    }
    }
    void solve()
    {
    if(n == 1)
    {
    puts("-1");
    return ;
    }
    cnt = dep = top = atype = 0;
    memset(head, -1, sizeof(head));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    memset(vis, false, sizeof(vis));
    memset(belong, 0, sizeof(belong));
    memset(in, 0, sizeof(in));
    memset(out, 0, sizeof(out));
    memset(sum, 0, sizeof(sum));
    int u, v;
    for(int i = 0; i < m; i++)
    {
    scanf("%d%d", &u, &v);
    addedge(u, v);
    }
    for(int i = 1; i <= n; i++)
    if(!dfn[i])
    Tarjan(i);
    if(atype == 1)
    {
    puts("-1");
    return ;
    }
    for(int u = 1; u <= n; u++)
    for(int i = head[u]; i != -1; i = edge[i].nxt)
    {
    int v = edge[i].to;
    if(belong[u] != belong[v])
    {
    out[belong[u]]++;
    in[belong[v]]++;
    }
    }
    ll ans = 0, tmp;
    for(int i = 1; i <= atype; i++)
    if(in[i] == 0 || out[i] == 0)
    {
    tmp = sum[i];
    ans = max(ans, tmp*(tmp-1) + (n-tmp)*(n-tmp-1) + tmp*(n-tmp) - m);
    }
    printf("%I64d\n", ans);
    }
    int main()
    {
    int T;
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase++)
    {
    scanf("%d%d", &n, &m);
    printf("Case %d: ", kase);
    solve();
    }
    return 0;
    }

    评论

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试