求边数最小且为奇数条边的环
枚举每一条边进行dfs。
剪枝:
1.搜索时记录每个点的搜索深度,如果现在的深度小于所记录的深度,才能访问这个点。
2.当出现最小的3时,就不用继续搜索了。
#include <iostream>
#include <vector>
using namespace std;
struct Node {
int a, b;
}ns[20005];
int n, m, tm[1002], cnt, ans, ca=1, idx;
int mp[1002][1002], from, to;
vector<int> vec[1002];
void input() {
int i, j, a, b;
scanf( "%d %d", &n, &m );
for( i=0; i<=n; ++i ) vec[i].clear();
for( i=0; i<=n; ++i ) {
tm[i] = 0;
for( j=0; j<=n; ++j ) {
mp[i][j] = 0;
}
}
idx = 0;
for( i=0; i<m; ++i ) {
scanf( "%d %d", &a, &b );
if( mp[a][b] ) continue;
ns[idx].a = a;
ns[idx].b = b;
idx ++;
vec[a].push_back(b);
vec[b].push_back(a);
mp[a][b] = mp[b][a] = 1;
}
}
void dfs( int u, int deep ) {
int i, j, sz;
if( mp[u][to] ) {
++ deep;
if( (deep&1) && deep < ans ) {
ans = deep;
}
return;
}
if( ans == 3 || deep >= ans) return;
if( deep >= tm[u] && tm[u] ) return;
tm[u] = deep;
sz = vec[u].size();
for( i=0; i<sz; ++i ) dfs( vec[u][i], deep+1 );
}
void solve() {
int i, j, a, b;
ans = 1000000;
for( i=0; i<idx; ++i ) {
from = ns[i].a;
to = ns[i].b;
mp[from][to] = mp[to][from] = 0;
memset( tm, 0, sizeof(tm) );
dfs( from, 1 );
if( ans == 3 ) break;
mp[from][to] = mp[to][from] = 1;
}
if( ans == 1000000 ) printf( "Case %d: Poor JYY.\n", ca++ );
else printf( "Case %d: JYY has to use %d balls.\n", ca++, ans );
}
int main() {
// freopen( "c:/aaa.txt", "r", stdin );
int T;
scanf( "%d", &T );
while( T-- ) {
input();
solve();
}
return 0;
}
差不多的一题:
2.hdoj 1599 find the mincost route
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
struct Node {
int a, b;
}ns[1002];
int mp[102][102], n, m, ans, cnt;
vector<int> vec[102];
void input() {
int i, j, a, b, c;
for( i=0; i<=n; ++i ) vec[i].clear();
for( i=0; i<=n; ++i ) {
for( j=0; j<=n; ++j ) {
mp[i][j] = 1000000;
}
}
cnt = 0;
for( i=0; i<m; ++i ) {
scanf( "%d %d %d", &a, &b, &c );
if( c > mp[a][b] ) continue;
if( mp[a][b] == 1000000 ) {
ns[cnt].a = a;
ns[cnt++].b = b;
vec[a].push_back(b);
vec[b].push_back(a);
}
mp[a][b] = mp[b][a] = c;
}
/*
for( i=1; i<=n; ++i ) {
for( j=1; j<=n; ++j ) {
printf( "%10d ", mp[i][j]);
}
printf( "\n" );
}*/
}
int spfa( int from, int to ) {
int Min[102], i, j, u, v, sz;
bool mark[102];
queue<int> Q;
for( i=0; i<=n; ++i ) {
Min[i] = 1000000;
mark[i] = 0;
}
Min[from] = 0;
Q.push( from );
mark[from] = 1;
while( !Q.empty() ) {
u = Q.front();
Q.pop();
mark[u] = 0;
sz = vec[u].size();
for( i=0; i<sz; ++i ) {
v = vec[u][i];
if( mp[u][v] == 1000000 ) continue;
if( Min[v] > Min[u] + mp[u][v] ) {
Min[v] = Min[u] + mp[u][v];
if( !mark[v] ) {
Q.push(v);
mark[v] = 1;
}
}
}
}
return Min[to];
}
void solve() {
int i, j, from, to, tp, temp;
ans = 1000000;
for( i=0; i<cnt; ++i ) {
from = ns[i].a;
to = ns[i].b;
tp = mp[from][to];
mp[from][to] = mp[to][from] = 1000000;
temp = spfa( from, to );
if( temp + tp < ans ) ans = temp + tp;
mp[from][to] = mp[to][from] = tp;
}
if( ans == 1000000 ) puts( "It's impossible." );
else printf( "%d\n", ans );
}
int main() {
// freopen( "c:/aaa.txt", "r", stdin );
while( scanf("%d %d", &n, &m) != EOF ) {
input();
solve();
}
return 0;
}
浙公网安备 33010602011771号