標籤:tor size work family mini string blog mat present
題目:
A university network is composed of N computers. System administrators gathered information on the traffic between nodes, and carefully divided the network into two subnetworks in order to minimize traffic between parts.
A disgruntled computer science student Vasya, after being expelled from the university, decided to have his revenge. He hacked into the university network and decided to reassign computers to maximize the traffic between two subnetworks.
Unfortunately, he found that calculating such worst subdivision is one of those problems he, being a student, failed to solve. So he asks you, a more successful CS student, to help him.
The traffic data are given in the form of matrix C, where Cij is the amount of data sent between ith and jth nodes (Cij = Cji, Cii = 0). The goal is to divide the network nodes into the two disjointed subsets A and B so as to maximize the sum ∑Cij (i∈A,j∈B).
Input
The first line of input contains a number of nodes N (2 <= N <= 20). The following N lines, containing N space-separated integers each, represent the traffic matrix C (0 <= Cij <= 10000).
Output file must contain a single integer -- the maximum traffic between the subnetworks.
Output
Output must contain a single integer -- the maximum traffic between the subnetworks.
Sample Input
30 50 3050 0 4030 40 0
Sample Output
90
題意:
這個題目看了好久,都不知道在講個什麼東西,百度也弄了好久,終於找到了有很好解析的解題報告;
我理解的大概就是這個意思啦!
輸入一個數代表子網的數量;
例如:題目例子為3
1 2 3
1 0 50 30
2 50 0 40
3 30 40 0
總共有3個子網,第1個子網和第2個子網之間的通訊量為50,第1個子網與第3個子網之間的通訊量為30;
就是這個意思差不多了!!!
題目要求的是讓你把這3個子網分為兩個部分,使得通訊量最大;
還是上面這個例子:
通訊量最大的情況是把1,2,3三個子網分為{1,3}和{2};
即子網2和子網1,3之間的通訊量是最大的
num_max=map[1][2]+map[3][2];
num_max=90;
我剛開始以為就只有三個子網,以為將每一行想相加就能得到最大值(笑cry),後來發現是20以內的子網數量;
那就需要用DFS啦!(看解析看了好久才理解怎麼寫)
那我們一開始就將所有的子網都放在一個集合中,另外一個是空的;
AC代碼:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;int map[25][25];int f[25];int n;int num_max;void dfs(int num,int sum){ f[num]=1; //做個標記,好知道我把誰扔空集合裡面了 int total=sum; // sum之前的,total是處理之後的 for (int i=1;i<=n;i++) { if (f[i]==1) total-=map[num][i]; //與num在一個集合裡面,減去權值 else total+=map[num][i]; //與num不在一個集合裡面的,加上權值 } num_max=num_max>total?num_max:total; //取最大值 for (int i=num+1;i<=n;i++) { if (total>sum) { dfs(i,total); //這個我理解的是:比如我輸入4,集合就會有{1,2},{1,3},{1,4},{2,3},{2,4},{3,4},{1,2,3},{4},{1,2,4},{3},{2,3,4},{1},{1,3,4},{2} f[i]=0; // 像第一次DFS時,num=1;這時第一個i取2,就會有{1,2}和{3,4}集合, } //迴圈完第一次以後,f[0]=0,就是講我倒回來把2從新集合中踢出去,i=3,把3丟進來,迴圈往複 }}int main(){ while (scanf("%d",&n)==1) { memset(f,0,sizeof(f)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) cin>>map[i][j]; num_max=-10000; dfs(1,0); //將1放入到空集合中 cout << num_max << endl; } return 0;}
覺得好難啊!!!主要是沒怎麼接觸過遞迴!!!看了好久才理清楚的思路!!!
Network Saboteur (DFS)