jzoj3539. Refraction damage

Title description

Description
In a game, there are n heroes. At the beginning, each hero receives damage with a value of ai. Each hero has a skill "refracting", that is, reducing the damage they receive and apportioning this part of the damage to others. For each refraction relationship, we use a number pair (xi, yi, zi) to represent the proportion of xi that takes damage to zi, and transfer these damages to yi (xi, yi are integers, and zi is a real number).

Find the actual total damage suffered by each hero after repeated refraction.

The
first line of Input is a positive integer: n, which means there are n heroes, and the n integers Ai in the second line indicate the initial damage received by each hero in turn. A positive integer m in the third line indicates that there are m pairs of refraction relations. In the next m lines, there are three numbers xi, yi, zi in each line, indicating the proportion of xi taking damage to zi and transferring these damages to yi.

Output
outputs n rows, and the ith row represents the actual total damage suffered by the ith hero at the end. Keep six decimal places.

Sample Input
3

1 0 2

3

1 2 0.3000

1 2 0.2000

2 1 0.5000

Sample Output
0.666667

0.333333

2.000000

Data Constraint
Insert picture description here

20%

The whole staff pits people
According to the simulation of the question, record the damage that can be rebounded in this round each time, and then roughly calculate how many rounds can be run according to the time.

100%

If you think of it, it is the sb problem.
Let f(x), which means that x receives + rebound damage (that is , the sum of the bombable damage stored in x in each round).
If there is an edge x–>y, and the ratio is z,
then f( y)=f(x)*z+y’s initial damage.
Because x has to bounce every time it receives a little bit of damage , the total damage from x received by y is f(x)*z
Gaussian elimination and
finally ans[ x]=f(x)*(1-∑z i ) ( the outgoing edge of z i ∈ x), that is, calculate the real damage x received

The solution is well received, but the card accuracy is poor

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define E 0.00000001
#define C 1000
using namespace std;

long double a[201][202];
int id[201];
long double ans[201];
long double tot[201];
int n,m,i,j,k,l;
long double s;

void work()
{
    
    
	fo(i,1,n)
	{
    
    
		fo(j,1,n)
		if (abs(a[i][j])>E)
		{
    
    
			if (!id[j])
			{
    
    
				id[j]=i;
				
				s=a[i][j];
				fo(k,j,n+1)
				a[i][k]/=s;
				
				break;
			}
			else
			{
    
    
				s=a[i][j];
				fo(k,j,n+1)
				a[i][k]-=s*a[id[j]][k];
			}
		}
	}
	
	fd(i,n,1)
	{
    
    
		ans[i]=a[id[i]][n+1];
		
		fo(j,1,i-1)
		a[j][n+1]-=ans[i]*a[j][i];
	}
}

int main()
{
    
    
//	freopen("damage6.in","r",stdin);
//	freopen("S8_4_2.in","r",stdin);
	
	scanf("%d",&n);
	fo(i,1,n)
	{
    
    
		scanf("%d",&j);
		
		a[i][i]=1*C;
		a[i][n+1]=j*C*C;
	}
	
	scanf("%d",&m);
	fo(i,1,m)
	{
    
    
		scanf("%d%d%Lf",&j,&k,&s);
		
		a[k][j]-=s*C;
		tot[j]+=s;
	}
	
	work();
	
	fo(i,1,n)
	printf("%0.6Lf\n",ans[i]*(1-tot[i])/C);
}

Guess you like

Origin blog.csdn.net/gmh77/article/details/98475014