poj3259 wormholes: http://poj.org/problem?id=3259
用spfa或者bellman-ford判断有无负环,我用的是spfa,使用cnt数组记录结点入队次数,次数大于等于n说明有负环。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 6000;
int n,m,w;
struct T
{
int to,w,nt;
};
T edge[MAX];
int cnt[510],head[510],visit[510];
int cnte;
queue<int> q;
void add(int u, int v , int w)
{
edge[cnte].to = v;
edge[cnte].w = w;
edge[cnte].nt = head[u];
head[u] = cnte;
cnte ++;
}
int spfa(void)
{
int dis[510];
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
visit[1] = 1;
cnt[1] ++;
q.push(1);
while(!q.empty()) {
int now = q.front(); q.pop();
visit[now] = 0;
for (int i = head[now]; i; i = edge[i].nt) {
if (dis[now] + edge[i].w < dis[edge[i].to]) {
dis[edge[i].to] = dis[now] + edge[i].w;
if (!visit[edge[i].to]) {
cnt[edge[i].to] ++;
if (cnt[edge[i].to] >= n) return 1;
q.push(edge[i].to);
visit[edge[i].to] = 1;
}
}
}
}
return 0;
}
int main(int argc, char const *argv[])
{
int f;
scanf("%d",&f);
while(f --) {
scanf("%d%d%d",&n,&m,&w);
cnte = 1;
memset(cnt,0,sizeof(cnt));
memset(visit,0,sizeof(visit));
memset(head,0,sizeof(head));
memset(edge,0,sizeof(edge));
int a,b,v;
for (int i = 0; i < m; i ++) {
scanf("%d%d%d",&a,&b,&v);
add(a,b,v);
add(b,a,v);
}
for (int i = 0; i < w; i ++) {
scanf("%d%d%d",&a,&b,&v);
add(a,b,-v);
}
if (spfa() ) {
puts("YES");
} else {
puts("NO");
}
}
return 0;
}
poj1270 Following Orders: http://poj.org/problem?id=1270
求有向图的全部拓扑序列,这里用的是递归+回溯的方法,比较坑的是输出要求是按字典序排序,贡献两发WA
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
const int MAX = 30;
int degree[MAX], cnt, matr[MAX][MAX], vis[MAX];
char s[MAX], ans[MAX];
map<char, int> mp;
void init(void)
{
cnt = 0;
mp.clear();
memset(matr, 0, sizeof(matr));
memset(vis, 0, sizeof(vis));
memset(s, 0, sizeof(s));
memset(degree, 0, sizeof(degree));
}
void dfstsort(int n);
void solve(void)
{
dfstsort(1);
}
void dfstsort(int n)
{
if (n > cnt) {
for (int i = 1; i <= cnt; i ++) {
printf("%c",ans[i]);
}
printf("\n");
return ;
}
for (int i = 1; i <= cnt; i ++) {
if (!vis[i] && degree[i] == 0) {
ans[n] = s[i];
vis[i] = 1;
for (int j = 1; j <= cnt; j ++) {
if (matr[i][j]) {
degree[j] --;
}
}
dfstsort(n + 1);
vis[i] = 0;
for (int j = 1; j <= cnt; j ++) {
if (matr[i][j]) {
degree[j] ++;
}
}
}
}
}
int main()
{
init();
char c, c1;
int isenter = 0;
int flag = 0, getc = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
++ flag;
// 字典序输出...
if (flag == 1) {
sort(s + 1, s + 1 + cnt);
for (int i = 1; i <= cnt; i ++) {
mp[s[i]] = i;
}
}
if (flag == 2) {
// for (int i = 1; i <= cnt; i ++) {
// cout << degree[i] << " " ;
// }
solve();
init();
flag = 0;
printf("\n");
}
continue;
}
if (c == ' ') continue;
if (flag == 0) {
s[++ cnt] = c;
}
if (flag == 1) {
if (getc == 0) {
c1 = c;
getc = 1;
} else {
matr[mp[c1]][mp[c]] = 1;
degree[mp[c]] ++;
getc = 0;
}
}
}
return 0;
}