關於臨界矩陣和鄰接表的使用情況
在很多圖論的題目中,如果題目本身沒有明確指出兩個頂點只有最多隻有一條直達的邊的話那麼最好使用鄰接表來存儲所有的邊,因爲鄰接矩陣會用某一條邊來覆蓋之前的邊,這條邊可以是最後輸入的邊,也可以是你設定了相應條件的邊,如果這下邊的邊權不一樣,就會很容易出現錯誤。比如求最短路的時候用之後出現的邊覆蓋了最短的邊,或者是求邊的入度出度的時候只記錄了一條邊以至於出錯。
HDU 3342 Legal or Not
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11758 Accepted Submission(s): 5532
We all know a master can have many prentices and a prentice may have a lot of masters too, it's legal. Nevertheless,some cows are not so honest, they hold illegal relationship. Take HH and 3xian for instant, HH is 3xian's master and, at the same time, 3xian is HH's master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not.
Please note that the "master and prentice" relation is transitive. It means that if A is B's master ans B is C's master, then A is C's master.
TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,..., N-1). We use their numbers instead of their names.
If it is legal, output "YES", otherwise "NO".
3 2 0 1 1 2 2 2 0 1 1 0 0 0
YES NO
使用鄰接矩陣的錯誤做法:
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>
using namespace std;
typedef long long ll;
const ll inf = 1061109567;
const int maxn = 1002;
int n,m;
int mat[maxn][maxn];
int vex_in[maxn];
int TopoSort(){
queue<int> q;
int s[maxn]={0};
int cnt=0;
for(int i=0;i<n;i++){
if(vex_in[i]==0) q.push(i);
}
while(!q.empty()){
int p=q.front();
q.pop();
s[p]=1;
cnt++;
for(int i=0;i<n;i++){
if(mat[p][i]){
vex_in[i]--;
if(vex_in[i]==0) q.push(i);
}
}
}
/*for(int i=0;i<n;i++)
if(!s[i]) return 0;*/
if(cnt!=n) return 0;
return 1;
}
int main(int argc, char const *argv[])
{
while(cin>>n>>m&&m&&n){
for(int i=0;i<n;i++){
vex_in[i]=0;
for(int j=0;j<n;j++){
mat[i][j]=0;
}
}
int a,b;
for(int i=0;i<m;i++){
cin>>a>>b;
mat[a][b]=1;
vex_in[b]++;
}
if(TopoSort())
cout<<"YES";
else cout<<"NO";
cout<<endl;
}
return 0;
}
此時莫名奇妙的wa,雖然我沒見到測試樣例,但是猜測可能是存在上述說的情況。於是改用鄰接表a了。
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>
using namespace std;
typedef long long ll;
const ll inf = 1061109567;
const int maxn = 1002;
int n,m;
int mat[maxn][maxn];
std::vector<int> edge[maxn];
int vex_in[maxn];
int TopoSort(){
queue<int> q;
//int s[maxn]={0};
int cnt=0;
for(int i=0;i<n;i++){
if(vex_in[i]==0) q.push(i);
}
while(!q.empty()){
int p=q.front();
q.pop();
//s[p]=1;
cnt++;
int len=edge[p].size();
for(int i=0;i<len;i++){
vex_in[edge[p][i]]--;
if(vex_in[edge[p][i]]==0) q.push(edge[p][i]);
}
}
/*for(int i=0;i<n;i++)
if(!s[i]) return 0;*/
if(cnt!=n) return 0;
return 1;
}
int main(int argc, char const *argv[])
{
while(cin>>n>>m&&m&&n){
for(int i=0;i<n;i++){
vex_in[i]=0;
edge[i].clear();
}
int a,b;
for(int i=0;i<m;i++){
cin>>a>>b;
edge[a].push_back(b);
vex_in[b]++;
}
if(TopoSort())
cout<<"YES";
else cout<<"NO";
cout<<endl;
}
return 0;
}