JZOJ 3414. 【NOIP2013模拟】开心小屋

题目

Description

Kc来到开心小屋。开心小屋是用来提升心情的。在这个小屋中有n个房间,一些房间之间有门连通。从房间i到达房间j,心情值可以加上-10000<=Cij<=10000,当然Cij可能是负的。现在kc失恋了,所以他想要知道他是否可以在这个小屋中无限地增加他的心情值,也就是无限地绕着一个环走?

请帮kc求出最小的环需要经过的房间数,来使他的心情无限增加。
 

Input

第一行给出,1<=n<=300,1<=m<=5000。分别表示房间数及门的数量。

接下来m行,每行四个数:i,j,Cij,Cji

 

Output

输出文件包括一行,及最小的环需要经过的房间数。

保证不会出现自环及重边。
 

Sample Input

4 4
1 2 -10 3
1 3 1 -10
2 4 -10 -1
3 4 0 -3

Sample Output

4
样例解释:
1--->3--->4-->2-->1为最小的符合题意的环长度为4.
 
 

Data Constraint

对30%的数据,n<=10;

对60%的数据,,n<=100;

对100%的数据,n<=300;

 

分析

 

  • dfs可以过 666
  • 一个超级厉害的剪枝 心情一到负数就return
  • 因为同一个环,总有第二个点可以满足全为正数

 

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,start,ans=1e9;
 4 int a[305][305];
 5 bool vis[305];
 6 void dfs(int x,int lev,int sum)
 7 {
 8     if(lev>ans||sum<0) return;
 9     if(x==start&&lev>0)
10     {
11       if(sum>0)
12        ans=min(ans,lev); 
13       return;
14     }
15     for(int i=1;i<=n;i++)
16      if(a[x][i]<=10000&&!vis[i])
17      {
18        vis[i]=1;
19        dfs(i,lev+1,sum+a[x][i]);
20        vis[i]=0;
21      }
22     return;
23 }
24 int main()
25 {
26     scanf("%d%d",&n,&m);
27     memset(a,0x3f,sizeof(a));
28     for(int i=1,u,v,x,y;i<=m;i++)
29     {
30       scanf("%d%d%d%d",&u,&v,&x,&y);
31       a[u][v]=x;a[v][u]=y;
32     }
33     for(int i=1;i<=n;i++)
34      start=i,dfs(i,0,0);
35     cout<<ans;
36 }

 

posted @ 2019-10-31 20:36  Melted_czj  阅读(176)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色