图论的题目,求一个人通过虫洞或者普通路径进行行走,能不能在出发前回到原地,抽象成最短路回到原地权值为负。
我数组开505,RE了,结果改大了就A了。
| MDK | 3259 | Accepted | 860K | 813MS | G++ | 2604B | 2011-11-09 20:54:46 |
#define MAXN 5050
struct edge {
int v;
int dis;
edge(int a=0,int b=0):v(a),dis(b){}
}tmp;
vector<edge> mat[MAXN];
int n,m,w;
int minl[MAXN],count_n[MAXN];
int spfa(int n,int s) {
int i;
bool used[MAXN];
SET(used,0);SET(count_n,0);
for( i = 0;i<MAXN;i++) {
minl[i] = INT_MAX;
}
minl[s] = 0;used[s] = 1;count_n[s]++;
queue<int> q; q.push(s);
while(!q.empty()) {
int u = q.front();q.pop();
used[u] = 0;
for(i = 0;i<mat[u].size();i++) {
tmp = mat[u][i];
if(minl[tmp.v] > minl[u] + tmp.dis) {
minl[tmp.v] = minl[u] + tmp.dis;
if(! used[tmp.v]) {
used[tmp.v] = 1;
q.push(tmp.v);
count_n[tmp.v] ++;
if(count_n[tmp.v] >= n) {
return -1;
}
}
}
}
}
return 1;
}
void init() {
int s,e,t;
SCFT(n,m,w);
F(i,m+w+5) mat[i].clear();
F(i,m) {
SCFT(s,e,t);
mat[--s].push_back(edge(--e,t));
mat[e].push_back(edge(s,t));
}
F(i,w) {
SCFT(s,e,t);
mat[--s].push_back(edge(--e,-t));
}
}
int main() {
int cas;SCF(cas);
while(cas --) {
init();
bool flag = 0;
for(int i = 0;i<n;i++) {
spfa(n,i);
//F(j,n) DB(minl[j]<<" -- ");
if(minl[i] <0) {
flag = 1;
break;
}
}
if(flag) {
puts("YES");
} else {
puts("NO");
}
}
}
稍稍改进了一下:
#define MAXN 5050
struct edge {
int v;
int dis;
edge(int a=0,int b=0):v(a),dis(b){}
}tmp;
vector<edge> mat[MAXN];
int n,m,w;
int minl[MAXN],count_n[MAXN];
int spfa(int n,int s) {
int i;
bool used[MAXN];
SET(used,0);SET(count_n,0);
for( i = 0;i<MAXN;i++) {
minl[i] = INT_MAX;
}
minl[s] = 0;used[s] = 1;count_n[s]++;
queue<int> q; q.push(s);
while(!q.empty()) {
int u = q.front();q.pop();
used[u] = 0;
for(i = 0;i<mat[u].size();i++) {
tmp = mat[u][i];
if(minl[tmp.v] > minl[u] + tmp.dis) {
minl[tmp.v] = minl[u] + tmp.dis;
if(! used[tmp.v]) {
used[tmp.v] = 1;
q.push(tmp.v);
count_n[tmp.v] ++;
if(count_n[tmp.v] >= n) {
return -1;
}
}
}
}
}
return 1;
}
void init() {
int s,e,t;
SCFT(n,m,w);
F(i,m+w+5) mat[i].clear();
F(i,m) {
SCFT(s,e,t);
mat[--s].push_back(edge(--e,t));
mat[e].push_back(edge(s,t));
}
F(i,w) {
SCFT(s,e,t);
mat[--s].push_back(edge(--e,-t));
}
}
int main() {
int cas;SCF(cas);
while(cas --) {
init();
bool flag = 0;
// for(int i = 0;i<n;i++) {
//
// //F(j,n) DB(minl[j]<<" -- ");
// if(minl[i] <0) {
// flag = 1;
// break;
// }
// }
if(spfa(n,0) == -1) {
flag = 1;
}
if(flag) {
puts("YES");
} else {
puts("NO");
}
}
}
时间变成 110MS了
继续思考,良久,发现这是个判断有没有负环的图论,bellman,SPFA都能够判断,广问个位大牛,还有其他好的判断负环的算法吗?
浙公网安备 33010602011771号