Gym 101673E Is-A? Has-A? Who Knowz-A?
阿新 • • 發佈:2018-11-17
題目:傳送門
題意:有n個關係,有m個詢問,關係有a is b,a has b 注意(a is b!=b is a),然後 is和has都具有傳遞性。
每次詢問問你a,b的關係是否正確
思路:根據is關係和has關係建邊,如果是is關係,那麼兩個點之間的邊都是is邊,如果是has關係,兩個點之間的路徑就會存在至少一個has,這樣用dfs或者最短路都可以解決。
附上程式碼:
#include<cstdio> #include<iostream> #include<map> #include<cstring> #include<string> #include<algorithm> using namespace std; map<string, int>p; typedef long long ll; #define inf 0x3f3f3f3f int gx[510][510]; int hh[510][510]; int cnt = 1; void flod() { for (int i = 1; i < cnt; i++) { for (int z = 1; z < cnt; z++) { for (int k = 1; k < cnt; k++) { if (gx[z][i]<inf&&gx[i][k]<inf) gx[z][k] = min(gx[z][k], gx[z][i] + gx[i][k]); if (hh[z][i]<inf&&hh[i][k]<inf) hh[z][k] = min(hh[z][k],hh[z][i] + hh[i][k]); if (hh[z][k] < 0) hh[z][k] = -1; } } } } int main(void) { int n, m; p.clear(); for (int i = 0; i < 510; i++) { for (int z = 0; z < 510; z++) { if (i == z) gx[i][z] = 0; else gx[i][z] = gx[z][i] = inf; } } for (int i = 0; i < 510; i++) { for (int z = 0; z < 510; z++) { if (i == z) hh[i][z] = 0; else hh[i][z] = hh[z][i] = inf; } } cin >> n >> m; for (int i = 0; i < n; i++) { string a, b, c; cin >> a >> b >> c; int x1, x2; if (p[a] == 0) { p[a] = cnt++; } if (p[c] == 0) { p[c] = cnt++; } x1 = p[a]; x2 = p[c]; if (b[0] == 'i') { gx[x1][x2] = 0; hh[x1][x2] = min(hh[x1][x2],0);//這裡是個bug } else if (b[0] == 'h') { hh[x1][x2] = -1; } } flod(); for (int i = 0; i < m; i++) { string a, b, c; cin >> a >> b >> c; cout << "Query " << i + 1 << ": "; if (b[0] == 'i') { if (gx[p[a]][p[c]] == 0) { cout << "true" << endl; } else cout << "false" << endl; } else if (b[0] == 'h') { if (hh[p[a]][p[c]] < 0) { cout << "true" << endl; } else cout << "false" << endl; } } return 0; }