比赛时愣是没读懂
题意:有N 个城市 每一个城市都有 val 个 士兵 , 有几条路连接
当敌方攻击你的某个城市时 该城市以及与该城市相连接的城市的士兵总数 要大于 K
不大于 K 该城市就被攻陷。士兵被俘虏 则不能支援别的城市
求最后一共同拥有多少城市不被攻陷。以及士兵总数
思路:先计算该点能支援到的总士兵数
然后将 总数小于 K 的取出 减去相连的城市上的总士兵数
直到剩下的点都大于K
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #include <time.h>; #define cler(arr, val) memset(arr, val, sizeof(arr)) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 1032; const int MAXM = 444; const int INF = 0x3f3f3f3f; const int mod = 1000000007; vector<int>G[MAXN]; int val[MAXN],vis[MAXN],ans,num,orz[MAXN],man; void init() { for(int i=0; i<MAXN; i++) G[i].clear(); cler(val,0); cler(vis,0); } int main() { int n,k; //IN; while(scanf("%d%d",&n,&k),n+k) { init(); for(int i=0; i<n; i++) { int a,m; scanf("%d%d",&val[i],&m); for(int j=0; j<m; j++) { scanf("%d",&a); G[i].push_back(a); } } for(int i=0; i<n; i++) { orz[i]=val[i]; for(int j=0; j<G[i].size(); j++) orz[i]+=val[G[i][j]]; } ans=0,num=0; queue<int>q; for(int i=0; i<n; i++) if(orz[i]<k) q.push(i),vis[i]=1; while(!q.empty()) { int i=q.front(); q.pop(); for(int j=0; j<G[i].size(); j++) { orz[G[i][j]]-=val[i]; if(orz[G[i][j]]<k&&!vis[G[i][j]]) q.push(G[i][j]),vis[G[i][j]]=1; } } for(int i=0; i<n; i++) if(!vis[i]) num++,ans+=val[i]; printf("%d %d\n",num,ans); } return 0; }
时间: 2024-11-02 23:40:52