Networking
1 0
2 3
1 2 37
2 1 17
1 2 68
3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32
5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12
0
Sample Output
0
17
16
26
#include
#include
#include
const int MAXN=55;
using namespace std;
int father[MAXN];
int P ,R,sum;
struct Edge{
int s,e,length;
}edge[10020];
bool cmp(Edge a,Edge b){
return a.lengthf2)
f2[father]=f1;
else
f1[father]=f2;
return true;
}
int kruskal(){
sum=0;
for(int i=1;i<=P;i++)
father[i]=i;
sort(edge,edge+R+1,cmp);
for(int i=1;i<=R;i++){
if(Union(edge[i].s,edge[i].e)){
sum+=edge[i].length;
}
}
return sum;
}
int main(){
while(scanf("%d",&P)&& (P!=0)){
scanf("%d",&R);
for(int i=1;i<=R;i++)
scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].length);
kruskal();
printf("%d\n",sum);
}
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=1000000;
int map[100][100];
int dis[100];
bool vis[100];
int prim(int n){
for(int i=1;i<=n;++i)
dis[i]=map[i][1],vis[i]=false;
vis[1]=true;
int ret=0;
while(1){
int min=inf,mj=-1;
for(int i=1;i<=n;++i)
if(!vis[i]&&dis[i]map[i][mj])
dis[i]=map[i][mj];
}
return ret;
}
int main(){
int n,m;
while( cin>>n>>m,n ){
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(i==j)map[i][j]=0;
else map[i][j]=inf;
while(m--){
int x,y,c; cin>>x>>y>>c;
if(c
吝嗇的國度
輸入
M(1<=M<=5)組
每組第一行輸一N(1<=N<=100000)和S(1<=S<=100000),城市的總個數,參觀者所在城市的編號隨後的N-1行,每行有a,b(1<=a,b<=N),第a號和第b號城市之間有一條路連通。
1 10 1 1 9 1 8 8 10 10 3 8 6 1 2 10 4 9 5 3 7輸出 每組測試數據輸N個正整數,其中,第i個數表示從S走到i號城市,必須要經過的上一個城市的編號。(其中i=S時,請輸出-1)
-1 1 10 10 9 8 3 1 1 8
#include
#include
#include
#include
#include
#include
using namespace std;
int pre[100005];
vectorv[100005];
void DFS(int cur)
{
for(int i = 0; i < v[cur].size(); ++i)
{
if(pre[v[cur][i]]) continue; //若存在父節點則繼續遍歷
pre[v[cur][i]] = cur; //相連節點的父節點爲cur
DFS(v[cur][i]); //深搜到底,把一條路上父節點全部找出
}
}
int main()
{
int ncase, num, cur, i, x, y;
scanf("%d", &ncase);
while(ncase--)
{
memset(v, 0, sizeof(v));
memset(pre, 0, sizeof(pre));
scanf("%d%d", &num, &cur);
pre[cur] = - 1; //起點沒有父節點
for(i = 0; i < num - 1; ++i)
{
scanf("%d%d", &x, &y);
v[x].push_back(y); //x與y相連
v[y].push_back(x); //y與x也肯定相連
}
DFS(cur); //起點開始深搜
for(i = 1; i <= num; ++i)
printf("%d ", pre[i]); //每個節點的父節點都保存在pri數組,輸出即可
}
return 0;/*簡單的深搜,加邊的時候要加入雙向邊。然後深搜每個點即可。
將無根樹化爲有根樹,對每個節點進行遍歷,記錄從起點開始的父節點。*/
}
佈線問題
1
4 6
1 2 10
2 3 10
3 1 10
1 4 1
2 4 1
3 4 1
1 3 5 6
樣例輸出
4
#include
#include
#include
#include
#include
#include
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
struct Node
{
Node(){}
Node(int num,int len):len(len),num(num){}
int len,num;
};
bool operator<(const Node& n1,const Node& n2)
{
return n1.len>n2.len;
}
const int MAX=510;
const int MAXE=250000;
int Head[MAX],Next[MAXE],Num[MAXE],Len[MAXE];
int Dis[MAX],top;
void add(int u,int v,int len)
{
Num[top]=v;
Next[top]=Head[u];
Len[top]=len;
Head[u]=top++;
}
bool InQ[MAX];
int main()
{
//freopen("input.txt","r",stdin);
priority_queue q;
int t,m,n,a,b,l;
scanf("%d",&t);
while(t--)
{
top=0;CLR(Head,-1);
CLR(Dis,0x3f);
scanf("%d%d",&m,&n);
for(int i=0;i!=n;i++)
{
scanf("%d%d%d",&a,&b,&l);
add(a-1,b-1,l);add(b-1,a-1,l);
}
Dis[0]=0;
q.push(Node(0,0));
while(!q.empty())
{
Node t=q.top();q.pop();
if(Dis[t.num]!=t.len) continue;
for(int i=Head[t.num];i!=-1;i=Next[i])
{
if(Dis[Num[i]]>Len[i])
{
Dis[Num[i]]=Len[i];
q.push(Node(Num[i],Len[i]));
}
}
}
int minl=0x3f3f3f3f;
for(int i=0;i!=m;i++)
{
scanf("%d",&l);
minl=min(minl,l);
}
printf("%d\n",accumulate(Dis,Dis+m,0)+minl);
}
}
2
6 3 1
4 1 1
9 3 2
7 1 1
樣例輸出
3
-1
//搜索
#include
#include
#include
#include
#include
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
bitset<1000000> Hash;
const int MAX_STEP=100000;
int WQ[MAX_STEP][4],Goal[3],Cap[3],goalval;
int head=0,tail=0;
void movw(int numfrom,int numto,int other)
{
int total=WQ[head][numfrom]+WQ[head][numto];
WQ[tail][other]=WQ[head][other];
WQ[tail][3]=WQ[head][3]+1;
if(total>Cap[numto])
{
WQ[tail][numfrom]=total-Cap[numto];
WQ[tail][numto]=Cap[numto];
}
else
{
WQ[tail][numfrom]=0;
WQ[tail][numto]=total;
}
int hashval=WQ[tail][0]*10000+WQ[tail][1]*100+WQ[tail][2];
if(hashval==goalval) throw WQ[head][3]+1;
if(WQ[head][numfrom]!=0 && !Hash[hashval])
{
Hash[hashval]=true;
if(++tail==MAX_STEP) tail=0;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
Hash.reset();
scanf("%d%d%d%d%d%d",&Cap[0],&Cap[1],&Cap[2],&Goal[0],&Goal[1],&Goal[2]);
head=0,tail=0,goalval=Goal[0]*10000+Goal[1]*100+Goal[2];
if(Goal[1]==0 && Goal[2]==0 && Goal[0]==Cap[0]) {puts("0");continue;}
WQ[tail][0]=Cap[0];WQ[tail][1]=0;WQ[tail][2]=0;WQ[tail][3]=0;
++tail;
try{
while(head!=tail)
{
movw(0,1,2);movw(1,2,0);movw(0,2,1);movw(1,0,2);movw(2,1,0);movw(2,0,1);
if(++head==MAX_STEP) head=0;
}
puts("-1");
}catch(int step)
{
printf("%d\n",step);
}
}
}
2
3
4
樣例輸出
3
16
#include
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
int n;
scanf("%d",&n);
int sum=1,m=n-2;
while(m>=1)
{
if(m%2==1)
sum=(sum*n)%10003;
n=n*n%10003;
m=m/2;
}
printf("%d\n",sum);
}
return 0;
}
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
/*1
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
25
*/
#include
#include
#define MAX 101
int height[MAX][MAX];
int tmp[MAX][MAX];
int r,c;
int dir[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1};
bool isvalueable(int x, int y)
{
if(x > 0 && x <= r && y > 0 && y <= c)return true;
return false;
}
int dfs(int x, int y)
{
if(tmp[x][y] > 0)return tmp[x][y];
int max = 0,i;
for(i = 0; i < 4; i ++){
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(isvalueable(tx,ty)){
if(height[x][y] > height[tx][ty]){
int m = dfs(tx, ty)+1;
if(max < m)max = m;
}
}
}
return max;
}
int main()
{
int t;
int i, j, res;
scanf("%d", &t);
while(t--){
res = 0;
scanf("%d%d", &r, &c);
for(i = 1;i <= r; i ++){
for(j = 1; j <= c; j ++){
scanf("%d", &height[i][j]);
tmp[i][j] = 0;
}
}
for(i = 1; i <= r; i ++){
for(j = 1; j <= c; j ++){
tmp[i][j] = dfs(i, j);
if(tmp[i][j] > res)res = tmp[i][j];
}
}
printf("%d\n",res+1);
}
return 0;
}
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
Sample Output
2 1
棋盤問題, 棋子擺放的位置只能是#, 且不能同行和同列. 由於我採用的是按行遞增的順序來搜索的, 因此不可能出現同行的情況, 對於同列的情況, 我設置了一個變量col[], 來保存列的訪問狀態, 對於之前訪問過的列, 棋子是不能再放在這一列上的.
dfs(begin, num) 代表將第k-num棵棋子放在begin行上, 然後就剩下num-1棵棋子需要放在begin行下面. 當然, 可能存在第num棵棋子根本無法放在begin行上的情況, 對於這種情況, dfs就回溯到上一個dfs調用的地方, 重新開始, 而如果遇到num=1, 且第begin行的一些列可以放的話, 就將方案數相應增加.
#include
using namespace std;
char pic[8][8];
int col[8];//列的訪問狀態
int c;
int n,k;
void dfs(int begin,int num)
{
for(int j=0;j> n >> k) && !(n==-1 && k==-1))
{
c=0;
for(int i=0;i> pic[i][j];
for(int i=0;i