实验9 回溯法实验一
OJ练习
1. 畅通工程续:http://acm.hdu.edu.cn/showproblem.php?pid=1874
2. 最短路径问题:http://acm.hdu.edu.cn/showproblem.php?pid=3790
3. 最短路:http://acm.hdu.edu.cn/showproblem.php?pid=2544
4*. Choose the best route:http://acm.hdu.edu.cn/showproblem.php?pid=2680
5*. 一个人的旅行:http://acm.hdu.edu.cn/showproblem.php?pid=2066
6*. HDU Today:http://acm.hdu.edu.cn/showproblem.php?pid=2112
7*. Bus System:http://acm.hdu.edu.cn/showproblem.php?pid=1690
8*. 0 or 1:http://acm.hdu.edu.cn/showproblem.php?pid=4370
实验内容
1. 编程实现Dijkstra算法。
输入:第1行第1个值表示顶点个数,第2个值表示边个数;第2行开始为边及权重。例:
5 7 0
0 1 10
0 3 30
0 4 100
1 2 50
2 4 10
3 2 20
3 4 60
输出:顶点0到每一个顶点的最短路径长度。例:
0 10 50 30 60
源代码:
#include
using namespace std;
typedef long long ll;
const int maxn = 10010;
const ll INF = 2147483647;
typedef pairint> pli;
struct node
{
int to,cost;
node(int t,int c):to(t),cost(c){}
bool operator < (const node & a)const {
return cost > a.cost;
}
};
vector E[maxn];
ll d[maxn];
priority_queuevector,greater > Q;
int main()
{
int n,m,st;
cin>> n>>m>>st;
for(int i=1;i<=m;i++)
{
int x,y,v;
scanf("%d %d %d",&x, &y ,&v);
E[x].push_back({y,v});
}
for(int i=1;i<=n;i++)
{
d[i]=INF;
}
d[st] = 0;
Q.push({0,st});
while ( Q.size() )
{
pli now = Q.top();Q.pop();
ll cost = now.first;
int p=now.second;
if(cost >= INF)
continue;
for(int i=0;iint v = E[p][i].to;
if(d[v] > cost + E[p][i].cost)
{
d[v] = cost + E[p][i].cost;
Q.push({d[v],v});
}
}
}
for(int i=0;iif(i!= n-1)
cout<" ";
else
cout<cout<
#include
using namespace std;
typedef long long ll;
const int maxn = 10010;
const ll INF = 2147483647;
typedef pairint> pli;
int a[10],book[10];
void dfs(int step)
{
if(step == 10)
{
int i;
int t=(a[1]*100+a[2]*10+a[3]);
int k=(a[7]*100+a[8]*10+a[9]);
int g=(a[4]*100+a[5]*10+a[6]);
if(t*3==k&&t*2==g && (t!=0))
{
for(i=1;i<10;i++)
{
printf("%d",a[i]);
if(i%3==0) printf(" ");
}
printf("\n");
return ;
}
}
for(int i=1;i<10;i++)
{
if(book[i]==0)
{
a[step] = i;
book[i] = 1;
dfs(step+1);
book[i] = 0;
}
}
return ;
}
int main()
{
dfs(1);
return 0;
}
输入:皇后的个数。输入示例:
4
输出:每一种方案及总方案数。输出示例:
0 1 0 0
0 0 0 2
3 0 0 0
0 0 1 0
2 0 0 0
0 0 0 3
总方案数为2。
源代码:
#include
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pairint> pli;
char a[maxn][maxn];
int m,n,b[maxn][maxn];
int x[maxn];
int place(int k)
{
int i=1;
while(i < k)
{
if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k))) return 0;
i++;
}
return 1;
}
void print(int x[],int n)
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
if(x[i]==j) printf(" %d ",i);
else printf(" 0 ");
printf("\n");
}
printf("\n");
}
void nqueue(int n){
int k=1,total=0;
x[k]=0;
while(k>0)
{
x[k]++;
while(k<=n && !place(k))
{
x[k]++;
}
if(x[k]<=n)
{
if(k==n)
{
print(x,n);
total++;
}
else
{
k++;
x[k]=0;
}
}
else
{
k--;
}
}
printf("%d\n",total);
}
int main()
{
int n;
scanf("%d",&n);
nqueue(n);
}
4. 油田问题
输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),即属于同一个八连块。例如,下图有两个八连块。
源代码:
#include
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pairint> pli;
char a[maxn][maxn];
int m,n,b[maxn][maxn];
void dfs(int x,int y,int ans)
{
if(x<0||x>=m||y<0||y>=n) return;
if(b[x][y]>0||a[x][y]=='*') return;
b[x][y]=ans;
for(int k=-1;k<=1;k++)
for(int t=-1;t<=1;t++)
if(k!=0||t!=0)
dfs(x+k,y+t,ans);
}
int main()
{
int i,j;
scanf("%d%d",&m,&n);
int cnt=0;
memset(b,0,sizeof(b));
for(i=0;iscanf("%s",a[i]);
for(i=0;ifor(j=0;jif(b[i][j]==0&&a[i][j]=='@')
dfs(i,j,++cnt);
printf("%d\n",cnt);
return 0;
}