秋招筆記:2018阿里中介軟體部門C/C++崗線上測評
題目:
今天我們看到的阿里巴巴提供的任何一項服務後邊都有著無數子系統和元件的支撐,子系統之間也互相依賴關聯,
其中任意一個環節出現問題都可能對上游鏈路產生影響。小明做為新人接收到的第一個任務就是去梳理所有的依賴關係,
小明和每個系統的負責人確認了依賴關係,記錄下呼叫對應系統的耗時,用這些資料分析端到端鏈路的數目和鏈路上最長的耗時。
輸入: 小明蒐集到的系統耗時和依賴列表
5 4 // 表示有5個系統和 4個依賴關係
3 // 呼叫1號系統耗時 3 ms
2 // 呼叫2號系統耗時 2 ms
10 // 呼叫3號系統耗時 10 ms
5 // 呼叫4號系統耗時 5 ms
7 // 呼叫5號系統耗時 7 ms
1 2 // 2號系統依賴1號系統
1 3 // 3號系統依賴1號系統
2 5 // 2號系統依賴5號系統
4 5 // 4號系統依賴5號系統
輸出: 呼叫鏈路的數目 和最大的耗時, 這裡有三條鏈路1->2->5,1->3, 4->5,最大的耗時是1到3的鏈路 3+10 = 13,無需考慮環形依賴的存在。
3 13
思路:
1、有向圖的遍歷。圖的儲存用的是鄰接表表示法,找出入度為0的點(根節點),然後dfs,將路徑儲存在一個二維的vector中,vector的size即為鏈路的數目,然後找出耗時最大的那一條。
2、評論有個老哥說可以用multimap來解決,才學疏淺以前確實沒有用過0.0,學習了。
3、如果有環怎麼辦?有環也不用怕,dfs的時候判斷一下下一個結點是否是根節點,是就結束,不是就繼續。
程式碼:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
vector<vector<int> > paths(0);
vector<int> path;
/*
連結串列的基本結構,data儲存的是是哪一個結點
*/
typedef struct node {
int data;
struct node *next;
}list ;
//鄰接表用來儲存圖
list *lists[1001];
/*
visit:該點是否被遍歷過,0沒有,1有
value:該點的權值
in:該點的入度,為0代表根節點
*/
int visit[1001];
int value[1001];
int in[1001];
/*
建立連結串列的頭結點
*/
list *create_list(int data)
{
list *head = (list *)malloc(sizeof(list));
if (head == NULL) {
cout << "head malloc error!" << endl;
exit(1);
}
head->data = data;
head->next = NULL;
return head;
}
/*
尾插法,插入資料
head: 連結串列的頭結點
data: 要插入的資料
*/
void insert_list(list *head, int data)
{
list *phead = head;
while(phead->next != NULL) {
phead = phead->next;
}
list *tmp = (list *)malloc(sizeof(list));
if (tmp == NULL) {
cout << "tmp malloc error\n" << endl;
exit(1);
}
tmp->data = data;
tmp->next = NULL;
phead->next = tmp;
}
//dfs
void dfs(int i)
{
path.push_back(i);
if(lists[i]->next == NULL) {
paths.push_back(path);
} else {
list *phead = lists[i]->next;
while (phead != NULL) {
if(visit[phead->data] == 0) {
visit[phead->data] = 1;
dfs(phead->data);
visit[phead->data] = 0;
}
phead = phead->next;
}
}
path.pop_back();
return ;
}
void print_list(list *head)
{
list *phead = head;
while(phead) {
cout << phead->data << " ";
phead = phead->next;
}
cout << endl;
}
int main()
{
int m, n;
scanf("%d %d", &m, &n);
memset(value, 0, sizeof(value));
memset(visit, 0, sizeof(visit));
memset(in, 0, sizeof(in));
list *head;
for(int i = 1; i <= m; i++) {
scanf("%d", &value[i]);
head = create_list(i);
lists[i] = head;
}
int p, q;
for(int i = 0; i < n; i++) {
scanf("%d %d", &p, &q);
in[q]++;
insert_list(lists[p], q);
}
/*
for (int i = 1; i <= m; i++) {
print_list(lists[i]);
}
*/
for (int i = 1; i <= m; i++) {
if (in[i] == 0) {
dfs(i);
}
}
int max = -1, sum = 0;
//cout << "paths size is:" << paths.size() << endl;
for (int i = 0; i < paths.size(); i++) {
sum = 0;
for(int j = 0; j < paths[i].size(); j++) {
//cout << paths[i][j] << " ";
sum += value[paths[i][j]];
if (sum > max) {
max = sum;
}
}
//cout << endl;
}
cout << paths.size() << " " << max << endl;
return 0;
}
心得體會:
6號的時候投的簡歷,結果一直都沒有給回訊息,本以為涼了呢,16號的時候突然接到了郵件,還是挺意外的,雖然深知自己只是炮灰,但還是想去見識一下大廠的面試,希望可以過筆試吧。
努力努力再努力。