D - New Friends

lightsong發表於2024-04-20

D - New Friends

https://atcoder.jp/contests/abc350/tasks/abc350_d

思路

此sns網路,可能包括若干個連同子圖,

對於每個子圖, 計算 連通子圖中 成員數目, 和 連線數目,

計算全連線子圖,需要的總的連線數目, 減去當前連線數目, 得到每個連通子圖的 還需要建立的 連線數目,

累加所有子圖的 待建立連線資料, 得到答案。

Code

https://atcoder.jp/contests/abc350/submissions/52621997

/******************************** GRAPH START ***************************************/
// Graph class represents a directed graph
// using adjacency list representation
class Graph {
public:
    map<int, list<int> > adj;
    
    // for search linked block
    map<int, bool> visited;
    long long linkcnt = 0;
    set<int> members;

    // function to add an edge to graph
    void addEdge(int v, int w);

    // DFS traversal of the vertices
    // reachable from v
    void DFS(int v);
};

void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w); // Add w to v’s list.
}

void Graph::DFS(int v)
{
    // Mark the current node as visited and
    // print it
    visited[v] = true;
    members.insert(v);
//    cout << v << " ";

    // Recur for all the vertices adjacent
    // to this vertex
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
    {
        linkcnt++;

        if (!visited[*i]){
            DFS(*i);
        }
    }
}

/******************************** GRAPH END ***************************************/

/*
https://atcoder.jp/contests/abcxxx/tasks/abcxxx_d
*/

int n,m;
Graph gp;

int main()
{
    cin >> n >> m;
    
    for(int i=0; i<m; i++){
        int a,b;
        
        cin >> a >> b;
        
        gp.addEdge(a, b);
        gp.addEdge(b, a);
    }

    long long sum = 0;

    vector<bool> visited(n+1, false);
    for(int i=1; i<=n; i++){
        if (visited[i]){
            continue;
        }
        
        gp.linkcnt = 0;
        gp.members.clear();
        gp.visited.clear();
        
        gp.DFS(i);
        
        long long linkcnt = gp.linkcnt/2;
        long long memcnt = gp.members.size();

//        cout << "linkcnt=" << linkcnt << endl;
//        cout << "memcnt=" << memcnt << endl;

        long long alllink = memcnt*(memcnt-1)/2;

        sum += alllink - linkcnt;
        
        for(auto one: gp.members){
            visited[one] = true;
        }
    }
    
    cout << sum << endl;
    
    return 0;
}

相關文章